PageRenderTime 108ms CodeModel.GetById 19ms app.highlight 64ms RepoModel.GetById 0ms app.codeStats 1ms

/drivers/media/dvb/frontends/dib8000.c

https://bitbucket.org/ndreys/linux-sunxi
C | 2669 lines | 2103 code | 419 blank | 147 comment | 471 complexity | 94e638911f0533d70808edf3d38f4f05 MD5 | raw file
Possible License(s): GPL-2.0, LGPL-2.0, AGPL-1.0

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

   1/*
   2 * Linux-DVB Driver for DiBcom's DiB8000 chip (ISDB-T).
   3 *
   4 * Copyright (C) 2009 DiBcom (http://www.dibcom.fr/)
   5 *
   6 * This program is free software; you can redistribute it and/or
   7 *  modify it under the terms of the GNU General Public License as
   8 *  published by the Free Software Foundation, version 2.
   9 */
  10#include <linux/kernel.h>
  11#include <linux/slab.h>
  12#include <linux/i2c.h>
  13#include <linux/mutex.h>
  14
  15#include "dvb_math.h"
  16
  17#include "dvb_frontend.h"
  18
  19#include "dib8000.h"
  20
  21#define LAYER_ALL -1
  22#define LAYER_A   1
  23#define LAYER_B   2
  24#define LAYER_C   3
  25
  26#define FE_CALLBACK_TIME_NEVER 0xffffffff
  27#define MAX_NUMBER_OF_FRONTENDS 6
  28
  29static int debug;
  30module_param(debug, int, 0644);
  31MODULE_PARM_DESC(debug, "turn on debugging (default: 0)");
  32
  33#define dprintk(args...) do { if (debug) { printk(KERN_DEBUG "DiB8000: "); printk(args); printk("\n"); } } while (0)
  34
  35#define FE_STATUS_TUNE_FAILED 0
  36
  37struct i2c_device {
  38	struct i2c_adapter *adap;
  39	u8 addr;
  40	u8 *i2c_write_buffer;
  41	u8 *i2c_read_buffer;
  42	struct mutex *i2c_buffer_lock;
  43};
  44
  45struct dib8000_state {
  46	struct dib8000_config cfg;
  47
  48	struct i2c_device i2c;
  49
  50	struct dibx000_i2c_master i2c_master;
  51
  52	u16 wbd_ref;
  53
  54	u8 current_band;
  55	u32 current_bandwidth;
  56	struct dibx000_agc_config *current_agc;
  57	u32 timf;
  58	u32 timf_default;
  59
  60	u8 div_force_off:1;
  61	u8 div_state:1;
  62	u16 div_sync_wait;
  63
  64	u8 agc_state;
  65	u8 differential_constellation;
  66	u8 diversity_onoff;
  67
  68	s16 ber_monitored_layer;
  69	u16 gpio_dir;
  70	u16 gpio_val;
  71
  72	u16 revision;
  73	u8 isdbt_cfg_loaded;
  74	enum frontend_tune_state tune_state;
  75	u32 status;
  76
  77	struct dvb_frontend *fe[MAX_NUMBER_OF_FRONTENDS];
  78
  79	/* for the I2C transfer */
  80	struct i2c_msg msg[2];
  81	u8 i2c_write_buffer[4];
  82	u8 i2c_read_buffer[2];
  83	struct mutex i2c_buffer_lock;
  84};
  85
  86enum dib8000_power_mode {
  87	DIB8000M_POWER_ALL = 0,
  88	DIB8000M_POWER_INTERFACE_ONLY,
  89};
  90
  91static u16 dib8000_i2c_read16(struct i2c_device *i2c, u16 reg)
  92{
  93	u16 ret;
  94	struct i2c_msg msg[2] = {
  95		{.addr = i2c->addr >> 1, .flags = 0, .len = 2},
  96		{.addr = i2c->addr >> 1, .flags = I2C_M_RD, .len = 2},
  97	};
  98
  99	if (mutex_lock_interruptible(i2c->i2c_buffer_lock) < 0) {
 100		dprintk("could not acquire lock");
 101		return 0;
 102	}
 103
 104	msg[0].buf    = i2c->i2c_write_buffer;
 105	msg[0].buf[0] = reg >> 8;
 106	msg[0].buf[1] = reg & 0xff;
 107	msg[1].buf    = i2c->i2c_read_buffer;
 108
 109	if (i2c_transfer(i2c->adap, msg, 2) != 2)
 110		dprintk("i2c read error on %d", reg);
 111
 112	ret = (msg[1].buf[0] << 8) | msg[1].buf[1];
 113	mutex_unlock(i2c->i2c_buffer_lock);
 114	return ret;
 115}
 116
 117static u16 dib8000_read_word(struct dib8000_state *state, u16 reg)
 118{
 119	u16 ret;
 120
 121	if (mutex_lock_interruptible(&state->i2c_buffer_lock) < 0) {
 122		dprintk("could not acquire lock");
 123		return 0;
 124	}
 125
 126	state->i2c_write_buffer[0] = reg >> 8;
 127	state->i2c_write_buffer[1] = reg & 0xff;
 128
 129	memset(state->msg, 0, 2 * sizeof(struct i2c_msg));
 130	state->msg[0].addr = state->i2c.addr >> 1;
 131	state->msg[0].flags = 0;
 132	state->msg[0].buf = state->i2c_write_buffer;
 133	state->msg[0].len = 2;
 134	state->msg[1].addr = state->i2c.addr >> 1;
 135	state->msg[1].flags = I2C_M_RD;
 136	state->msg[1].buf = state->i2c_read_buffer;
 137	state->msg[1].len = 2;
 138
 139	if (i2c_transfer(state->i2c.adap, state->msg, 2) != 2)
 140		dprintk("i2c read error on %d", reg);
 141
 142	ret = (state->i2c_read_buffer[0] << 8) | state->i2c_read_buffer[1];
 143	mutex_unlock(&state->i2c_buffer_lock);
 144
 145	return ret;
 146}
 147
 148static u32 dib8000_read32(struct dib8000_state *state, u16 reg)
 149{
 150	u16 rw[2];
 151
 152	rw[0] = dib8000_read_word(state, reg + 0);
 153	rw[1] = dib8000_read_word(state, reg + 1);
 154
 155	return ((rw[0] << 16) | (rw[1]));
 156}
 157
 158static int dib8000_i2c_write16(struct i2c_device *i2c, u16 reg, u16 val)
 159{
 160	struct i2c_msg msg = {.addr = i2c->addr >> 1, .flags = 0, .len = 4};
 161	int ret = 0;
 162
 163	if (mutex_lock_interruptible(i2c->i2c_buffer_lock) < 0) {
 164		dprintk("could not acquire lock");
 165		return -EINVAL;
 166	}
 167
 168	msg.buf    = i2c->i2c_write_buffer;
 169	msg.buf[0] = (reg >> 8) & 0xff;
 170	msg.buf[1] = reg & 0xff;
 171	msg.buf[2] = (val >> 8) & 0xff;
 172	msg.buf[3] = val & 0xff;
 173
 174	ret = i2c_transfer(i2c->adap, &msg, 1) != 1 ? -EREMOTEIO : 0;
 175	mutex_unlock(i2c->i2c_buffer_lock);
 176
 177	return ret;
 178}
 179
 180static int dib8000_write_word(struct dib8000_state *state, u16 reg, u16 val)
 181{
 182	int ret;
 183
 184	if (mutex_lock_interruptible(&state->i2c_buffer_lock) < 0) {
 185		dprintk("could not acquire lock");
 186		return -EINVAL;
 187	}
 188
 189	state->i2c_write_buffer[0] = (reg >> 8) & 0xff;
 190	state->i2c_write_buffer[1] = reg & 0xff;
 191	state->i2c_write_buffer[2] = (val >> 8) & 0xff;
 192	state->i2c_write_buffer[3] = val & 0xff;
 193
 194	memset(&state->msg[0], 0, sizeof(struct i2c_msg));
 195	state->msg[0].addr = state->i2c.addr >> 1;
 196	state->msg[0].flags = 0;
 197	state->msg[0].buf = state->i2c_write_buffer;
 198	state->msg[0].len = 4;
 199
 200	ret = (i2c_transfer(state->i2c.adap, state->msg, 1) != 1 ?
 201			-EREMOTEIO : 0);
 202	mutex_unlock(&state->i2c_buffer_lock);
 203
 204	return ret;
 205}
 206
 207static const s16 coeff_2k_sb_1seg_dqpsk[8] = {
 208	(769 << 5) | 0x0a, (745 << 5) | 0x03, (595 << 5) | 0x0d, (769 << 5) | 0x0a, (920 << 5) | 0x09, (784 << 5) | 0x02, (519 << 5) | 0x0c,
 209		(920 << 5) | 0x09
 210};
 211
 212static const s16 coeff_2k_sb_1seg[8] = {
 213	(692 << 5) | 0x0b, (683 << 5) | 0x01, (519 << 5) | 0x09, (692 << 5) | 0x0b, 0 | 0x1f, 0 | 0x1f, 0 | 0x1f, 0 | 0x1f
 214};
 215
 216static const s16 coeff_2k_sb_3seg_0dqpsk_1dqpsk[8] = {
 217	(832 << 5) | 0x10, (912 << 5) | 0x05, (900 << 5) | 0x12, (832 << 5) | 0x10, (-931 << 5) | 0x0f, (912 << 5) | 0x04, (807 << 5) | 0x11,
 218		(-931 << 5) | 0x0f
 219};
 220
 221static const s16 coeff_2k_sb_3seg_0dqpsk[8] = {
 222	(622 << 5) | 0x0c, (941 << 5) | 0x04, (796 << 5) | 0x10, (622 << 5) | 0x0c, (982 << 5) | 0x0c, (519 << 5) | 0x02, (572 << 5) | 0x0e,
 223		(982 << 5) | 0x0c
 224};
 225
 226static const s16 coeff_2k_sb_3seg_1dqpsk[8] = {
 227	(699 << 5) | 0x14, (607 << 5) | 0x04, (944 << 5) | 0x13, (699 << 5) | 0x14, (-720 << 5) | 0x0d, (640 << 5) | 0x03, (866 << 5) | 0x12,
 228		(-720 << 5) | 0x0d
 229};
 230
 231static const s16 coeff_2k_sb_3seg[8] = {
 232	(664 << 5) | 0x0c, (925 << 5) | 0x03, (937 << 5) | 0x10, (664 << 5) | 0x0c, (-610 << 5) | 0x0a, (697 << 5) | 0x01, (836 << 5) | 0x0e,
 233		(-610 << 5) | 0x0a
 234};
 235
 236static const s16 coeff_4k_sb_1seg_dqpsk[8] = {
 237	(-955 << 5) | 0x0e, (687 << 5) | 0x04, (818 << 5) | 0x10, (-955 << 5) | 0x0e, (-922 << 5) | 0x0d, (750 << 5) | 0x03, (665 << 5) | 0x0f,
 238		(-922 << 5) | 0x0d
 239};
 240
 241static const s16 coeff_4k_sb_1seg[8] = {
 242	(638 << 5) | 0x0d, (683 << 5) | 0x02, (638 << 5) | 0x0d, (638 << 5) | 0x0d, (-655 << 5) | 0x0a, (517 << 5) | 0x00, (698 << 5) | 0x0d,
 243		(-655 << 5) | 0x0a
 244};
 245
 246static const s16 coeff_4k_sb_3seg_0dqpsk_1dqpsk[8] = {
 247	(-707 << 5) | 0x14, (910 << 5) | 0x06, (889 << 5) | 0x16, (-707 << 5) | 0x14, (-958 << 5) | 0x13, (993 << 5) | 0x05, (523 << 5) | 0x14,
 248		(-958 << 5) | 0x13
 249};
 250
 251static const s16 coeff_4k_sb_3seg_0dqpsk[8] = {
 252	(-723 << 5) | 0x13, (910 << 5) | 0x05, (777 << 5) | 0x14, (-723 << 5) | 0x13, (-568 << 5) | 0x0f, (547 << 5) | 0x03, (696 << 5) | 0x12,
 253		(-568 << 5) | 0x0f
 254};
 255
 256static const s16 coeff_4k_sb_3seg_1dqpsk[8] = {
 257	(-940 << 5) | 0x15, (607 << 5) | 0x05, (915 << 5) | 0x16, (-940 << 5) | 0x15, (-848 << 5) | 0x13, (683 << 5) | 0x04, (543 << 5) | 0x14,
 258		(-848 << 5) | 0x13
 259};
 260
 261static const s16 coeff_4k_sb_3seg[8] = {
 262	(612 << 5) | 0x12, (910 << 5) | 0x04, (864 << 5) | 0x14, (612 << 5) | 0x12, (-869 << 5) | 0x13, (683 << 5) | 0x02, (869 << 5) | 0x12,
 263		(-869 << 5) | 0x13
 264};
 265
 266static const s16 coeff_8k_sb_1seg_dqpsk[8] = {
 267	(-835 << 5) | 0x12, (684 << 5) | 0x05, (735 << 5) | 0x14, (-835 << 5) | 0x12, (-598 << 5) | 0x10, (781 << 5) | 0x04, (739 << 5) | 0x13,
 268		(-598 << 5) | 0x10
 269};
 270
 271static const s16 coeff_8k_sb_1seg[8] = {
 272	(673 << 5) | 0x0f, (683 << 5) | 0x03, (808 << 5) | 0x12, (673 << 5) | 0x0f, (585 << 5) | 0x0f, (512 << 5) | 0x01, (780 << 5) | 0x0f,
 273		(585 << 5) | 0x0f
 274};
 275
 276static const s16 coeff_8k_sb_3seg_0dqpsk_1dqpsk[8] = {
 277	(863 << 5) | 0x17, (930 << 5) | 0x07, (878 << 5) | 0x19, (863 << 5) | 0x17, (0 << 5) | 0x14, (521 << 5) | 0x05, (980 << 5) | 0x18,
 278		(0 << 5) | 0x14
 279};
 280
 281static const s16 coeff_8k_sb_3seg_0dqpsk[8] = {
 282	(-924 << 5) | 0x17, (910 << 5) | 0x06, (774 << 5) | 0x17, (-924 << 5) | 0x17, (-877 << 5) | 0x15, (565 << 5) | 0x04, (553 << 5) | 0x15,
 283		(-877 << 5) | 0x15
 284};
 285
 286static const s16 coeff_8k_sb_3seg_1dqpsk[8] = {
 287	(-921 << 5) | 0x19, (607 << 5) | 0x06, (881 << 5) | 0x19, (-921 << 5) | 0x19, (-921 << 5) | 0x14, (713 << 5) | 0x05, (1018 << 5) | 0x18,
 288		(-921 << 5) | 0x14
 289};
 290
 291static const s16 coeff_8k_sb_3seg[8] = {
 292	(514 << 5) | 0x14, (910 << 5) | 0x05, (861 << 5) | 0x17, (514 << 5) | 0x14, (690 << 5) | 0x14, (683 << 5) | 0x03, (662 << 5) | 0x15,
 293		(690 << 5) | 0x14
 294};
 295
 296static const s16 ana_fe_coeff_3seg[24] = {
 297	81, 80, 78, 74, 68, 61, 54, 45, 37, 28, 19, 11, 4, 1022, 1017, 1013, 1010, 1008, 1008, 1008, 1008, 1010, 1014, 1017
 298};
 299
 300static const s16 ana_fe_coeff_1seg[24] = {
 301	249, 226, 164, 82, 5, 981, 970, 988, 1018, 20, 31, 26, 8, 1012, 1000, 1018, 1012, 8, 15, 14, 9, 3, 1017, 1003
 302};
 303
 304static const s16 ana_fe_coeff_13seg[24] = {
 305	396, 305, 105, -51, -77, -12, 41, 31, -11, -30, -11, 14, 15, -2, -13, -7, 5, 8, 1, -6, -7, -3, 0, 1
 306};
 307
 308static u16 fft_to_mode(struct dib8000_state *state)
 309{
 310	u16 mode;
 311	switch (state->fe[0]->dtv_property_cache.transmission_mode) {
 312	case TRANSMISSION_MODE_2K:
 313		mode = 1;
 314		break;
 315	case TRANSMISSION_MODE_4K:
 316		mode = 2;
 317		break;
 318	default:
 319	case TRANSMISSION_MODE_AUTO:
 320	case TRANSMISSION_MODE_8K:
 321		mode = 3;
 322		break;
 323	}
 324	return mode;
 325}
 326
 327static void dib8000_set_acquisition_mode(struct dib8000_state *state)
 328{
 329	u16 nud = dib8000_read_word(state, 298);
 330	nud |= (1 << 3) | (1 << 0);
 331	dprintk("acquisition mode activated");
 332	dib8000_write_word(state, 298, nud);
 333}
 334static int dib8000_set_output_mode(struct dvb_frontend *fe, int mode)
 335{
 336	struct dib8000_state *state = fe->demodulator_priv;
 337
 338	u16 outreg, fifo_threshold, smo_mode, sram = 0x0205;	/* by default SDRAM deintlv is enabled */
 339
 340	outreg = 0;
 341	fifo_threshold = 1792;
 342	smo_mode = (dib8000_read_word(state, 299) & 0x0050) | (1 << 1);
 343
 344	dprintk("-I-	Setting output mode for demod %p to %d",
 345			&state->fe[0], mode);
 346
 347	switch (mode) {
 348	case OUTMODE_MPEG2_PAR_GATED_CLK:	// STBs with parallel gated clock
 349		outreg = (1 << 10);	/* 0x0400 */
 350		break;
 351	case OUTMODE_MPEG2_PAR_CONT_CLK:	// STBs with parallel continues clock
 352		outreg = (1 << 10) | (1 << 6);	/* 0x0440 */
 353		break;
 354	case OUTMODE_MPEG2_SERIAL:	// STBs with serial input
 355		outreg = (1 << 10) | (2 << 6) | (0 << 1);	/* 0x0482 */
 356		break;
 357	case OUTMODE_DIVERSITY:
 358		if (state->cfg.hostbus_diversity) {
 359			outreg = (1 << 10) | (4 << 6);	/* 0x0500 */
 360			sram &= 0xfdff;
 361		} else
 362			sram |= 0x0c00;
 363		break;
 364	case OUTMODE_MPEG2_FIFO:	// e.g. USB feeding
 365		smo_mode |= (3 << 1);
 366		fifo_threshold = 512;
 367		outreg = (1 << 10) | (5 << 6);
 368		break;
 369	case OUTMODE_HIGH_Z:	// disable
 370		outreg = 0;
 371		break;
 372
 373	case OUTMODE_ANALOG_ADC:
 374		outreg = (1 << 10) | (3 << 6);
 375		dib8000_set_acquisition_mode(state);
 376		break;
 377
 378	default:
 379		dprintk("Unhandled output_mode passed to be set for demod %p",
 380				&state->fe[0]);
 381		return -EINVAL;
 382	}
 383
 384	if (state->cfg.output_mpeg2_in_188_bytes)
 385		smo_mode |= (1 << 5);
 386
 387	dib8000_write_word(state, 299, smo_mode);
 388	dib8000_write_word(state, 300, fifo_threshold);	/* synchronous fread */
 389	dib8000_write_word(state, 1286, outreg);
 390	dib8000_write_word(state, 1291, sram);
 391
 392	return 0;
 393}
 394
 395static int dib8000_set_diversity_in(struct dvb_frontend *fe, int onoff)
 396{
 397	struct dib8000_state *state = fe->demodulator_priv;
 398	u16 sync_wait = dib8000_read_word(state, 273) & 0xfff0;
 399
 400	if (!state->differential_constellation) {
 401		dib8000_write_word(state, 272, 1 << 9);	//dvsy_off_lmod4 = 1
 402		dib8000_write_word(state, 273, sync_wait | (1 << 2) | 2);	// sync_enable = 1; comb_mode = 2
 403	} else {
 404		dib8000_write_word(state, 272, 0);	//dvsy_off_lmod4 = 0
 405		dib8000_write_word(state, 273, sync_wait);	// sync_enable = 0; comb_mode = 0
 406	}
 407	state->diversity_onoff = onoff;
 408
 409	switch (onoff) {
 410	case 0:		/* only use the internal way - not the diversity input */
 411		dib8000_write_word(state, 270, 1);
 412		dib8000_write_word(state, 271, 0);
 413		break;
 414	case 1:		/* both ways */
 415		dib8000_write_word(state, 270, 6);
 416		dib8000_write_word(state, 271, 6);
 417		break;
 418	case 2:		/* only the diversity input */
 419		dib8000_write_word(state, 270, 0);
 420		dib8000_write_word(state, 271, 1);
 421		break;
 422	}
 423	return 0;
 424}
 425
 426static void dib8000_set_power_mode(struct dib8000_state *state, enum dib8000_power_mode mode)
 427{
 428	/* by default everything is going to be powered off */
 429	u16 reg_774 = 0x3fff, reg_775 = 0xffff, reg_776 = 0xffff,
 430		reg_900 = (dib8000_read_word(state, 900) & 0xfffc) | 0x3,
 431		reg_1280 = (dib8000_read_word(state, 1280) & 0x00ff) | 0xff00;
 432
 433	/* now, depending on the requested mode, we power on */
 434	switch (mode) {
 435		/* power up everything in the demod */
 436	case DIB8000M_POWER_ALL:
 437		reg_774 = 0x0000;
 438		reg_775 = 0x0000;
 439		reg_776 = 0x0000;
 440		reg_900 &= 0xfffc;
 441		reg_1280 &= 0x00ff;
 442		break;
 443	case DIB8000M_POWER_INTERFACE_ONLY:
 444		reg_1280 &= 0x00ff;
 445		break;
 446	}
 447
 448	dprintk("powermode : 774 : %x ; 775 : %x; 776 : %x ; 900 : %x; 1280 : %x", reg_774, reg_775, reg_776, reg_900, reg_1280);
 449	dib8000_write_word(state, 774, reg_774);
 450	dib8000_write_word(state, 775, reg_775);
 451	dib8000_write_word(state, 776, reg_776);
 452	dib8000_write_word(state, 900, reg_900);
 453	dib8000_write_word(state, 1280, reg_1280);
 454}
 455
 456static int dib8000_set_adc_state(struct dib8000_state *state, enum dibx000_adc_states no)
 457{
 458	int ret = 0;
 459	u16 reg_907 = dib8000_read_word(state, 907), reg_908 = dib8000_read_word(state, 908);
 460
 461	switch (no) {
 462	case DIBX000_SLOW_ADC_ON:
 463		reg_908 |= (1 << 1) | (1 << 0);
 464		ret |= dib8000_write_word(state, 908, reg_908);
 465		reg_908 &= ~(1 << 1);
 466		break;
 467
 468	case DIBX000_SLOW_ADC_OFF:
 469		reg_908 |= (1 << 1) | (1 << 0);
 470		break;
 471
 472	case DIBX000_ADC_ON:
 473		reg_907 &= 0x0fff;
 474		reg_908 &= 0x0003;
 475		break;
 476
 477	case DIBX000_ADC_OFF:	// leave the VBG voltage on
 478		reg_907 |= (1 << 14) | (1 << 13) | (1 << 12);
 479		reg_908 |= (1 << 5) | (1 << 4) | (1 << 3) | (1 << 2);
 480		break;
 481
 482	case DIBX000_VBG_ENABLE:
 483		reg_907 &= ~(1 << 15);
 484		break;
 485
 486	case DIBX000_VBG_DISABLE:
 487		reg_907 |= (1 << 15);
 488		break;
 489
 490	default:
 491		break;
 492	}
 493
 494	ret |= dib8000_write_word(state, 907, reg_907);
 495	ret |= dib8000_write_word(state, 908, reg_908);
 496
 497	return ret;
 498}
 499
 500static int dib8000_set_bandwidth(struct dvb_frontend *fe, u32 bw)
 501{
 502	struct dib8000_state *state = fe->demodulator_priv;
 503	u32 timf;
 504
 505	if (bw == 0)
 506		bw = 6000;
 507
 508	if (state->timf == 0) {
 509		dprintk("using default timf");
 510		timf = state->timf_default;
 511	} else {
 512		dprintk("using updated timf");
 513		timf = state->timf;
 514	}
 515
 516	dib8000_write_word(state, 29, (u16) ((timf >> 16) & 0xffff));
 517	dib8000_write_word(state, 30, (u16) ((timf) & 0xffff));
 518
 519	return 0;
 520}
 521
 522static int dib8000_sad_calib(struct dib8000_state *state)
 523{
 524/* internal */
 525	dib8000_write_word(state, 923, (0 << 1) | (0 << 0));
 526	dib8000_write_word(state, 924, 776);	// 0.625*3.3 / 4096
 527
 528	/* do the calibration */
 529	dib8000_write_word(state, 923, (1 << 0));
 530	dib8000_write_word(state, 923, (0 << 0));
 531
 532	msleep(1);
 533	return 0;
 534}
 535
 536int dib8000_set_wbd_ref(struct dvb_frontend *fe, u16 value)
 537{
 538	struct dib8000_state *state = fe->demodulator_priv;
 539	if (value > 4095)
 540		value = 4095;
 541	state->wbd_ref = value;
 542	return dib8000_write_word(state, 106, value);
 543}
 544
 545EXPORT_SYMBOL(dib8000_set_wbd_ref);
 546static void dib8000_reset_pll_common(struct dib8000_state *state, const struct dibx000_bandwidth_config *bw)
 547{
 548	dprintk("ifreq: %d %x, inversion: %d", bw->ifreq, bw->ifreq, bw->ifreq >> 25);
 549	dib8000_write_word(state, 23, (u16) (((bw->internal * 1000) >> 16) & 0xffff));	/* P_sec_len */
 550	dib8000_write_word(state, 24, (u16) ((bw->internal * 1000) & 0xffff));
 551	dib8000_write_word(state, 27, (u16) ((bw->ifreq >> 16) & 0x01ff));
 552	dib8000_write_word(state, 28, (u16) (bw->ifreq & 0xffff));
 553	dib8000_write_word(state, 26, (u16) ((bw->ifreq >> 25) & 0x0003));
 554
 555	dib8000_write_word(state, 922, bw->sad_cfg);
 556}
 557
 558static void dib8000_reset_pll(struct dib8000_state *state)
 559{
 560	const struct dibx000_bandwidth_config *pll = state->cfg.pll;
 561	u16 clk_cfg1;
 562
 563	// clk_cfg0
 564	dib8000_write_word(state, 901, (pll->pll_prediv << 8) | (pll->pll_ratio << 0));
 565
 566	// clk_cfg1
 567	clk_cfg1 = (1 << 10) | (0 << 9) | (pll->IO_CLK_en_core << 8) |
 568		(pll->bypclk_div << 5) | (pll->enable_refdiv << 4) | (1 << 3) |
 569		(pll->pll_range << 1) | (pll->pll_reset << 0);
 570
 571	dib8000_write_word(state, 902, clk_cfg1);
 572	clk_cfg1 = (clk_cfg1 & 0xfff7) | (pll->pll_bypass << 3);
 573	dib8000_write_word(state, 902, clk_cfg1);
 574
 575	dprintk("clk_cfg1: 0x%04x", clk_cfg1);	/* 0x507 1 0 1 000 0 0 11 1 */
 576
 577	/* smpl_cfg: P_refclksel=2, P_ensmplsel=1 nodivsmpl=1 */
 578	if (state->cfg.pll->ADClkSrc == 0)
 579		dib8000_write_word(state, 904, (0 << 15) | (0 << 12) | (0 << 10) |
 580				(pll->modulo << 8) | (pll->ADClkSrc << 7) | (0 << 1));
 581	else if (state->cfg.refclksel != 0)
 582		dib8000_write_word(state, 904, (0 << 15) | (1 << 12) |
 583				((state->cfg.refclksel & 0x3) << 10) | (pll->modulo << 8) |
 584				(pll->ADClkSrc << 7) | (0 << 1));
 585	else
 586		dib8000_write_word(state, 904, (0 << 15) | (1 << 12) | (3 << 10) | (pll->modulo << 8) | (pll->ADClkSrc << 7) | (0 << 1));
 587
 588	dib8000_reset_pll_common(state, pll);
 589}
 590
 591static int dib8000_reset_gpio(struct dib8000_state *st)
 592{
 593	/* reset the GPIOs */
 594	dib8000_write_word(st, 1029, st->cfg.gpio_dir);
 595	dib8000_write_word(st, 1030, st->cfg.gpio_val);
 596
 597	/* TODO 782 is P_gpio_od */
 598
 599	dib8000_write_word(st, 1032, st->cfg.gpio_pwm_pos);
 600
 601	dib8000_write_word(st, 1037, st->cfg.pwm_freq_div);
 602	return 0;
 603}
 604
 605static int dib8000_cfg_gpio(struct dib8000_state *st, u8 num, u8 dir, u8 val)
 606{
 607	st->cfg.gpio_dir = dib8000_read_word(st, 1029);
 608	st->cfg.gpio_dir &= ~(1 << num);	/* reset the direction bit */
 609	st->cfg.gpio_dir |= (dir & 0x1) << num;	/* set the new direction */
 610	dib8000_write_word(st, 1029, st->cfg.gpio_dir);
 611
 612	st->cfg.gpio_val = dib8000_read_word(st, 1030);
 613	st->cfg.gpio_val &= ~(1 << num);	/* reset the direction bit */
 614	st->cfg.gpio_val |= (val & 0x01) << num;	/* set the new value */
 615	dib8000_write_word(st, 1030, st->cfg.gpio_val);
 616
 617	dprintk("gpio dir: %x: gpio val: %x", st->cfg.gpio_dir, st->cfg.gpio_val);
 618
 619	return 0;
 620}
 621
 622int dib8000_set_gpio(struct dvb_frontend *fe, u8 num, u8 dir, u8 val)
 623{
 624	struct dib8000_state *state = fe->demodulator_priv;
 625	return dib8000_cfg_gpio(state, num, dir, val);
 626}
 627
 628EXPORT_SYMBOL(dib8000_set_gpio);
 629static const u16 dib8000_defaults[] = {
 630	/* auto search configuration - lock0 by default waiting
 631	 * for cpil_lock; lock1 cpil_lock; lock2 tmcc_sync_lock */
 632	3, 7,
 633	0x0004,
 634	0x0400,
 635	0x0814,
 636
 637	12, 11,
 638	0x001b,
 639	0x7740,
 640	0x005b,
 641	0x8d80,
 642	0x01c9,
 643	0xc380,
 644	0x0000,
 645	0x0080,
 646	0x0000,
 647	0x0090,
 648	0x0001,
 649	0xd4c0,
 650
 651	/*1, 32,
 652		0x6680 // P_corm_thres Lock algorithms configuration */
 653
 654	11, 80,			/* set ADC level to -16 */
 655	(1 << 13) - 825 - 117,
 656	(1 << 13) - 837 - 117,
 657	(1 << 13) - 811 - 117,
 658	(1 << 13) - 766 - 117,
 659	(1 << 13) - 737 - 117,
 660	(1 << 13) - 693 - 117,
 661	(1 << 13) - 648 - 117,
 662	(1 << 13) - 619 - 117,
 663	(1 << 13) - 575 - 117,
 664	(1 << 13) - 531 - 117,
 665	(1 << 13) - 501 - 117,
 666
 667	4, 108,
 668	0,
 669	0,
 670	0,
 671	0,
 672
 673	1, 175,
 674	0x0410,
 675	1, 179,
 676	8192,			// P_fft_nb_to_cut
 677
 678	6, 181,
 679	0x2800,			// P_coff_corthres_ ( 2k 4k 8k ) 0x2800
 680	0x2800,
 681	0x2800,
 682	0x2800,			// P_coff_cpilthres_ ( 2k 4k 8k ) 0x2800
 683	0x2800,
 684	0x2800,
 685
 686	2, 193,
 687	0x0666,			// P_pha3_thres
 688	0x0000,			// P_cti_use_cpe, P_cti_use_prog
 689
 690	2, 205,
 691	0x200f,			// P_cspu_regul, P_cspu_win_cut
 692	0x000f,			// P_des_shift_work
 693
 694	5, 215,
 695	0x023d,			// P_adp_regul_cnt
 696	0x00a4,			// P_adp_noise_cnt
 697	0x00a4,			// P_adp_regul_ext
 698	0x7ff0,			// P_adp_noise_ext
 699	0x3ccc,			// P_adp_fil
 700
 701	1, 230,
 702	0x0000,			// P_2d_byp_ti_num
 703
 704	1, 263,
 705	0x800,			//P_equal_thres_wgn
 706
 707	1, 268,
 708	(2 << 9) | 39,		// P_equal_ctrl_synchro, P_equal_speedmode
 709
 710	1, 270,
 711	0x0001,			// P_div_lock0_wait
 712	1, 285,
 713	0x0020,			//p_fec_
 714	1, 299,
 715	0x0062,			/* P_smo_mode, P_smo_rs_discard, P_smo_fifo_flush, P_smo_pid_parse, P_smo_error_discard */
 716
 717	1, 338,
 718	(1 << 12) |		// P_ctrl_corm_thres4pre_freq_inh=1
 719		(1 << 10) |
 720		(0 << 9) |		/* P_ctrl_pre_freq_inh=0 */
 721		(3 << 5) |		/* P_ctrl_pre_freq_step=3 */
 722		(1 << 0),		/* P_pre_freq_win_len=1 */
 723
 724	1, 903,
 725	(0 << 4) | 2,		// P_divclksel=0 P_divbitsel=2 (was clk=3,bit=1 for MPW)
 726
 727	0,
 728};
 729
 730static u16 dib8000_identify(struct i2c_device *client)
 731{
 732	u16 value;
 733
 734	//because of glitches sometimes
 735	value = dib8000_i2c_read16(client, 896);
 736
 737	if ((value = dib8000_i2c_read16(client, 896)) != 0x01b3) {
 738		dprintk("wrong Vendor ID (read=0x%x)", value);
 739		return 0;
 740	}
 741
 742	value = dib8000_i2c_read16(client, 897);
 743	if (value != 0x8000 && value != 0x8001 && value != 0x8002) {
 744		dprintk("wrong Device ID (%x)", value);
 745		return 0;
 746	}
 747
 748	switch (value) {
 749	case 0x8000:
 750		dprintk("found DiB8000A");
 751		break;
 752	case 0x8001:
 753		dprintk("found DiB8000B");
 754		break;
 755	case 0x8002:
 756		dprintk("found DiB8000C");
 757		break;
 758	}
 759	return value;
 760}
 761
 762static int dib8000_reset(struct dvb_frontend *fe)
 763{
 764	struct dib8000_state *state = fe->demodulator_priv;
 765
 766	dib8000_write_word(state, 1287, 0x0003);	/* sram lead in, rdy */
 767
 768	if ((state->revision = dib8000_identify(&state->i2c)) == 0)
 769		return -EINVAL;
 770
 771	if (state->revision == 0x8000)
 772		dprintk("error : dib8000 MA not supported");
 773
 774	dibx000_reset_i2c_master(&state->i2c_master);
 775
 776	dib8000_set_power_mode(state, DIB8000M_POWER_ALL);
 777
 778	/* always leave the VBG voltage on - it consumes almost nothing but takes a long time to start */
 779	dib8000_set_adc_state(state, DIBX000_VBG_ENABLE);
 780
 781	/* restart all parts */
 782	dib8000_write_word(state, 770, 0xffff);
 783	dib8000_write_word(state, 771, 0xffff);
 784	dib8000_write_word(state, 772, 0xfffc);
 785	dib8000_write_word(state, 898, 0x000c);	// sad
 786	dib8000_write_word(state, 1280, 0x004d);
 787	dib8000_write_word(state, 1281, 0x000c);
 788
 789	dib8000_write_word(state, 770, 0x0000);
 790	dib8000_write_word(state, 771, 0x0000);
 791	dib8000_write_word(state, 772, 0x0000);
 792	dib8000_write_word(state, 898, 0x0004);	// sad
 793	dib8000_write_word(state, 1280, 0x0000);
 794	dib8000_write_word(state, 1281, 0x0000);
 795
 796	/* drives */
 797	if (state->cfg.drives)
 798		dib8000_write_word(state, 906, state->cfg.drives);
 799	else {
 800		dprintk("using standard PAD-drive-settings, please adjust settings in config-struct to be optimal.");
 801		dib8000_write_word(state, 906, 0x2d98);	// min drive SDRAM - not optimal - adjust
 802	}
 803
 804	dib8000_reset_pll(state);
 805
 806	if (dib8000_reset_gpio(state) != 0)
 807		dprintk("GPIO reset was not successful.");
 808
 809	if (dib8000_set_output_mode(fe, OUTMODE_HIGH_Z) != 0)
 810		dprintk("OUTPUT_MODE could not be resetted.");
 811
 812	state->current_agc = NULL;
 813
 814	// P_iqc_alpha_pha, P_iqc_alpha_amp, P_iqc_dcc_alpha, ...
 815	/* P_iqc_ca2 = 0; P_iqc_impnc_on = 0; P_iqc_mode = 0; */
 816	if (state->cfg.pll->ifreq == 0)
 817		dib8000_write_word(state, 40, 0x0755);	/* P_iqc_corr_inh = 0 enable IQcorr block */
 818	else
 819		dib8000_write_word(state, 40, 0x1f55);	/* P_iqc_corr_inh = 1 disable IQcorr block */
 820
 821	{
 822		u16 l = 0, r;
 823		const u16 *n;
 824		n = dib8000_defaults;
 825		l = *n++;
 826		while (l) {
 827			r = *n++;
 828			do {
 829				dib8000_write_word(state, r, *n++);
 830				r++;
 831			} while (--l);
 832			l = *n++;
 833		}
 834	}
 835	state->isdbt_cfg_loaded = 0;
 836
 837	//div_cfg override for special configs
 838	if (state->cfg.div_cfg != 0)
 839		dib8000_write_word(state, 903, state->cfg.div_cfg);
 840
 841	/* unforce divstr regardless whether i2c enumeration was done or not */
 842	dib8000_write_word(state, 1285, dib8000_read_word(state, 1285) & ~(1 << 1));
 843
 844	dib8000_set_bandwidth(fe, 6000);
 845
 846	dib8000_set_adc_state(state, DIBX000_SLOW_ADC_ON);
 847	dib8000_sad_calib(state);
 848	dib8000_set_adc_state(state, DIBX000_SLOW_ADC_OFF);
 849
 850	dib8000_set_power_mode(state, DIB8000M_POWER_INTERFACE_ONLY);
 851
 852	return 0;
 853}
 854
 855static void dib8000_restart_agc(struct dib8000_state *state)
 856{
 857	// P_restart_iqc & P_restart_agc
 858	dib8000_write_word(state, 770, 0x0a00);
 859	dib8000_write_word(state, 770, 0x0000);
 860}
 861
 862static int dib8000_update_lna(struct dib8000_state *state)
 863{
 864	u16 dyn_gain;
 865
 866	if (state->cfg.update_lna) {
 867		// read dyn_gain here (because it is demod-dependent and not tuner)
 868		dyn_gain = dib8000_read_word(state, 390);
 869
 870		if (state->cfg.update_lna(state->fe[0], dyn_gain)) {
 871			dib8000_restart_agc(state);
 872			return 1;
 873		}
 874	}
 875	return 0;
 876}
 877
 878static int dib8000_set_agc_config(struct dib8000_state *state, u8 band)
 879{
 880	struct dibx000_agc_config *agc = NULL;
 881	int i;
 882	if (state->current_band == band && state->current_agc != NULL)
 883		return 0;
 884	state->current_band = band;
 885
 886	for (i = 0; i < state->cfg.agc_config_count; i++)
 887		if (state->cfg.agc[i].band_caps & band) {
 888			agc = &state->cfg.agc[i];
 889			break;
 890		}
 891
 892	if (agc == NULL) {
 893		dprintk("no valid AGC configuration found for band 0x%02x", band);
 894		return -EINVAL;
 895	}
 896
 897	state->current_agc = agc;
 898
 899	/* AGC */
 900	dib8000_write_word(state, 76, agc->setup);
 901	dib8000_write_word(state, 77, agc->inv_gain);
 902	dib8000_write_word(state, 78, agc->time_stabiliz);
 903	dib8000_write_word(state, 101, (agc->alpha_level << 12) | agc->thlock);
 904
 905	// Demod AGC loop configuration
 906	dib8000_write_word(state, 102, (agc->alpha_mant << 5) | agc->alpha_exp);
 907	dib8000_write_word(state, 103, (agc->beta_mant << 6) | agc->beta_exp);
 908
 909	dprintk("WBD: ref: %d, sel: %d, active: %d, alpha: %d",
 910		state->wbd_ref != 0 ? state->wbd_ref : agc->wbd_ref, agc->wbd_sel, !agc->perform_agc_softsplit, agc->wbd_sel);
 911
 912	/* AGC continued */
 913	if (state->wbd_ref != 0)
 914		dib8000_write_word(state, 106, state->wbd_ref);
 915	else			// use default
 916		dib8000_write_word(state, 106, agc->wbd_ref);
 917	dib8000_write_word(state, 107, (agc->wbd_alpha << 9) | (agc->perform_agc_softsplit << 8));
 918	dib8000_write_word(state, 108, agc->agc1_max);
 919	dib8000_write_word(state, 109, agc->agc1_min);
 920	dib8000_write_word(state, 110, agc->agc2_max);
 921	dib8000_write_word(state, 111, agc->agc2_min);
 922	dib8000_write_word(state, 112, (agc->agc1_pt1 << 8) | agc->agc1_pt2);
 923	dib8000_write_word(state, 113, (agc->agc1_slope1 << 8) | agc->agc1_slope2);
 924	dib8000_write_word(state, 114, (agc->agc2_pt1 << 8) | agc->agc2_pt2);
 925	dib8000_write_word(state, 115, (agc->agc2_slope1 << 8) | agc->agc2_slope2);
 926
 927	dib8000_write_word(state, 75, agc->agc1_pt3);
 928	dib8000_write_word(state, 923, (dib8000_read_word(state, 923) & 0xffe3) | (agc->wbd_inv << 4) | (agc->wbd_sel << 2));	/*LB : 929 -> 923 */
 929
 930	return 0;
 931}
 932
 933void dib8000_pwm_agc_reset(struct dvb_frontend *fe)
 934{
 935	struct dib8000_state *state = fe->demodulator_priv;
 936	dib8000_set_adc_state(state, DIBX000_ADC_ON);
 937	dib8000_set_agc_config(state, (unsigned char)(BAND_OF_FREQUENCY(fe->dtv_property_cache.frequency / 1000)));
 938}
 939EXPORT_SYMBOL(dib8000_pwm_agc_reset);
 940
 941static int dib8000_agc_soft_split(struct dib8000_state *state)
 942{
 943	u16 agc, split_offset;
 944
 945	if (!state->current_agc || !state->current_agc->perform_agc_softsplit || state->current_agc->split.max == 0)
 946		return FE_CALLBACK_TIME_NEVER;
 947
 948	// n_agc_global
 949	agc = dib8000_read_word(state, 390);
 950
 951	if (agc > state->current_agc->split.min_thres)
 952		split_offset = state->current_agc->split.min;
 953	else if (agc < state->current_agc->split.max_thres)
 954		split_offset = state->current_agc->split.max;
 955	else
 956		split_offset = state->current_agc->split.max *
 957			(agc - state->current_agc->split.min_thres) /
 958			(state->current_agc->split.max_thres - state->current_agc->split.min_thres);
 959
 960	dprintk("AGC split_offset: %d", split_offset);
 961
 962	// P_agc_force_split and P_agc_split_offset
 963	dib8000_write_word(state, 107, (dib8000_read_word(state, 107) & 0xff00) | split_offset);
 964	return 5000;
 965}
 966
 967static int dib8000_agc_startup(struct dvb_frontend *fe)
 968{
 969	struct dib8000_state *state = fe->demodulator_priv;
 970	enum frontend_tune_state *tune_state = &state->tune_state;
 971
 972	int ret = 0;
 973
 974	switch (*tune_state) {
 975	case CT_AGC_START:
 976		// set power-up level: interf+analog+AGC
 977
 978		dib8000_set_adc_state(state, DIBX000_ADC_ON);
 979
 980		if (dib8000_set_agc_config(state, (unsigned char)(BAND_OF_FREQUENCY(fe->dtv_property_cache.frequency / 1000))) != 0) {
 981			*tune_state = CT_AGC_STOP;
 982			state->status = FE_STATUS_TUNE_FAILED;
 983			break;
 984		}
 985
 986		ret = 70;
 987		*tune_state = CT_AGC_STEP_0;
 988		break;
 989
 990	case CT_AGC_STEP_0:
 991		//AGC initialization
 992		if (state->cfg.agc_control)
 993			state->cfg.agc_control(fe, 1);
 994
 995		dib8000_restart_agc(state);
 996
 997		// wait AGC rough lock time
 998		ret = 50;
 999		*tune_state = CT_AGC_STEP_1;
1000		break;
1001
1002	case CT_AGC_STEP_1:
1003		// wait AGC accurate lock time
1004		ret = 70;
1005
1006		if (dib8000_update_lna(state))
1007			// wait only AGC rough lock time
1008			ret = 50;
1009		else
1010			*tune_state = CT_AGC_STEP_2;
1011		break;
1012
1013	case CT_AGC_STEP_2:
1014		dib8000_agc_soft_split(state);
1015
1016		if (state->cfg.agc_control)
1017			state->cfg.agc_control(fe, 0);
1018
1019		*tune_state = CT_AGC_STOP;
1020		break;
1021	default:
1022		ret = dib8000_agc_soft_split(state);
1023		break;
1024	}
1025	return ret;
1026
1027}
1028
1029static const s32 lut_1000ln_mant[] =
1030{
1031	908, 7003, 7090, 7170, 7244, 7313, 7377, 7438, 7495, 7549, 7600
1032};
1033
1034s32 dib8000_get_adc_power(struct dvb_frontend *fe, u8 mode)
1035{
1036	struct dib8000_state *state = fe->demodulator_priv;
1037	u32 ix = 0, tmp_val = 0, exp = 0, mant = 0;
1038	s32 val;
1039
1040	val = dib8000_read32(state, 384);
1041	if (mode) {
1042		tmp_val = val;
1043		while (tmp_val >>= 1)
1044			exp++;
1045		mant = (val * 1000 / (1<<exp));
1046		ix = (u8)((mant-1000)/100); /* index of the LUT */
1047		val = (lut_1000ln_mant[ix] + 693*(exp-20) - 6908);
1048		val = (val*256)/1000;
1049	}
1050	return val;
1051}
1052EXPORT_SYMBOL(dib8000_get_adc_power);
1053
1054static void dib8000_update_timf(struct dib8000_state *state)
1055{
1056	u32 timf = state->timf = dib8000_read32(state, 435);
1057
1058	dib8000_write_word(state, 29, (u16) (timf >> 16));
1059	dib8000_write_word(state, 30, (u16) (timf & 0xffff));
1060	dprintk("Updated timing frequency: %d (default: %d)", state->timf, state->timf_default);
1061}
1062
1063static const u16 adc_target_16dB[11] = {
1064	(1 << 13) - 825 - 117,
1065	(1 << 13) - 837 - 117,
1066	(1 << 13) - 811 - 117,
1067	(1 << 13) - 766 - 117,
1068	(1 << 13) - 737 - 117,
1069	(1 << 13) - 693 - 117,
1070	(1 << 13) - 648 - 117,
1071	(1 << 13) - 619 - 117,
1072	(1 << 13) - 575 - 117,
1073	(1 << 13) - 531 - 117,
1074	(1 << 13) - 501 - 117
1075};
1076static const u8 permu_seg[] = { 6, 5, 7, 4, 8, 3, 9, 2, 10, 1, 11, 0, 12 };
1077
1078static void dib8000_set_channel(struct dib8000_state *state, u8 seq, u8 autosearching)
1079{
1080	u16 mode, max_constellation, seg_diff_mask = 0, nbseg_diff = 0;
1081	u8 guard, crate, constellation, timeI;
1082	u16 i, coeff[4], P_cfr_left_edge = 0, P_cfr_right_edge = 0, seg_mask13 = 0x1fff;	// All 13 segments enabled
1083	const s16 *ncoeff = NULL, *ana_fe;
1084	u16 tmcc_pow = 0;
1085	u16 coff_pow = 0x2800;
1086	u16 init_prbs = 0xfff;
1087	u16 ana_gain = 0;
1088
1089	if (state->ber_monitored_layer != LAYER_ALL)
1090		dib8000_write_word(state, 285, (dib8000_read_word(state, 285) & 0x60) | state->ber_monitored_layer);
1091	else
1092		dib8000_write_word(state, 285, dib8000_read_word(state, 285) & 0x60);
1093
1094	i = dib8000_read_word(state, 26) & 1;	// P_dds_invspec
1095	dib8000_write_word(state, 26, state->fe[0]->dtv_property_cache.inversion^i);
1096
1097	if (state->fe[0]->dtv_property_cache.isdbt_sb_mode) {
1098		//compute new dds_freq for the seg and adjust prbs
1099		int seg_offset =
1100			state->fe[0]->dtv_property_cache.isdbt_sb_segment_idx -
1101			(state->fe[0]->dtv_property_cache.isdbt_sb_segment_count / 2) -
1102			(state->fe[0]->dtv_property_cache.isdbt_sb_segment_count % 2);
1103		int clk = state->cfg.pll->internal;
1104		u32 segtodds = ((u32) (430 << 23) / clk) << 3;	// segtodds = SegBW / Fclk * pow(2,26)
1105		int dds_offset = seg_offset * segtodds;
1106		int new_dds, sub_channel;
1107		if ((state->fe[0]->dtv_property_cache.isdbt_sb_segment_count % 2) == 0)
1108			dds_offset -= (int)(segtodds / 2);
1109
1110		if (state->cfg.pll->ifreq == 0) {
1111			if ((state->fe[0]->dtv_property_cache.inversion ^ i) == 0) {
1112				dib8000_write_word(state, 26, dib8000_read_word(state, 26) | 1);
1113				new_dds = dds_offset;
1114			} else
1115				new_dds = dds_offset;
1116
1117			// We shift tuning frequency if the wanted segment is :
1118			//  - the segment of center frequency with an odd total number of segments
1119			//  - the segment to the left of center frequency with an even total number of segments
1120			//  - the segment to the right of center frequency with an even total number of segments
1121			if ((state->fe[0]->dtv_property_cache.delivery_system == SYS_ISDBT)
1122				&& (state->fe[0]->dtv_property_cache.isdbt_sb_mode == 1)
1123					&& (((state->fe[0]->dtv_property_cache.isdbt_sb_segment_count % 2)
1124					  && (state->fe[0]->dtv_property_cache.isdbt_sb_segment_idx ==
1125				  ((state->fe[0]->dtv_property_cache.isdbt_sb_segment_count / 2) + 1)))
1126					 || (((state->fe[0]->dtv_property_cache.isdbt_sb_segment_count % 2) == 0)
1127						 && (state->fe[0]->dtv_property_cache.isdbt_sb_segment_idx == (state->fe[0]->dtv_property_cache.isdbt_sb_segment_count / 2)))
1128					 || (((state->fe[0]->dtv_property_cache.isdbt_sb_segment_count % 2) == 0)
1129						 && (state->fe[0]->dtv_property_cache.isdbt_sb_segment_idx ==
1130							 ((state->fe[0]->dtv_property_cache.isdbt_sb_segment_count / 2) + 1)))
1131					)) {
1132				new_dds -= ((u32) (850 << 22) / clk) << 4;	// new_dds = 850 (freq shift in KHz) / Fclk * pow(2,26)
1133			}
1134		} else {
1135			if ((state->fe[0]->dtv_property_cache.inversion ^ i) == 0)
1136				new_dds = state->cfg.pll->ifreq - dds_offset;
1137			else
1138				new_dds = state->cfg.pll->ifreq + dds_offset;
1139		}
1140		dib8000_write_word(state, 27, (u16) ((new_dds >> 16) & 0x01ff));
1141		dib8000_write_word(state, 28, (u16) (new_dds & 0xffff));
1142		if (state->fe[0]->dtv_property_cache.isdbt_sb_segment_count % 2)
1143			sub_channel = ((state->fe[0]->dtv_property_cache.isdbt_sb_subchannel + (3 * seg_offset) + 1) % 41) / 3;
1144		else
1145			sub_channel = ((state->fe[0]->dtv_property_cache.isdbt_sb_subchannel + (3 * seg_offset)) % 41) / 3;
1146		sub_channel -= 6;
1147
1148		if (state->fe[0]->dtv_property_cache.transmission_mode == TRANSMISSION_MODE_2K
1149				|| state->fe[0]->dtv_property_cache.transmission_mode == TRANSMISSION_MODE_4K) {
1150			dib8000_write_word(state, 219, dib8000_read_word(state, 219) | 0x1);	//adp_pass =1
1151			dib8000_write_word(state, 190, dib8000_read_word(state, 190) | (0x1 << 14));	//pha3_force_pha_shift = 1
1152		} else {
1153			dib8000_write_word(state, 219, dib8000_read_word(state, 219) & 0xfffe);	//adp_pass =0
1154			dib8000_write_word(state, 190, dib8000_read_word(state, 190) & 0xbfff);	//pha3_force_pha_shift = 0
1155		}
1156
1157		switch (state->fe[0]->dtv_property_cache.transmission_mode) {
1158		case TRANSMISSION_MODE_2K:
1159			switch (sub_channel) {
1160			case -6:
1161				init_prbs = 0x0;
1162				break;	// 41, 0, 1
1163			case -5:
1164				init_prbs = 0x423;
1165				break;	// 02~04
1166			case -4:
1167				init_prbs = 0x9;
1168				break;	// 05~07
1169			case -3:
1170				init_prbs = 0x5C7;
1171				break;	// 08~10
1172			case -2:
1173				init_prbs = 0x7A6;
1174				break;	// 11~13
1175			case -1:
1176				init_prbs = 0x3D8;
1177				break;	// 14~16
1178			case 0:
1179				init_prbs = 0x527;
1180				break;	// 17~19
1181			case 1:
1182				init_prbs = 0x7FF;
1183				break;	// 20~22
1184			case 2:
1185				init_prbs = 0x79B;
1186				break;	// 23~25
1187			case 3:
1188				init_prbs = 0x3D6;
1189				break;	// 26~28
1190			case 4:
1191				init_prbs = 0x3A2;
1192				break;	// 29~31
1193			case 5:
1194				init_prbs = 0x53B;
1195				break;	// 32~34
1196			case 6:
1197				init_prbs = 0x2F4;
1198				break;	// 35~37
1199			default:
1200			case 7:
1201				init_prbs = 0x213;
1202				break;	// 38~40
1203			}
1204			break;
1205
1206		case TRANSMISSION_MODE_4K:
1207			switch (sub_channel) {
1208			case -6:
1209				init_prbs = 0x0;
1210				break;	// 41, 0, 1
1211			case -5:
1212				init_prbs = 0x208;
1213				break;	// 02~04
1214			case -4:
1215				init_prbs = 0xC3;
1216				break;	// 05~07
1217			case -3:
1218				init_prbs = 0x7B9;
1219				break;	// 08~10
1220			case -2:
1221				init_prbs = 0x423;
1222				break;	// 11~13
1223			case -1:
1224				init_prbs = 0x5C7;
1225				break;	// 14~16
1226			case 0:
1227				init_prbs = 0x3D8;
1228				break;	// 17~19
1229			case 1:
1230				init_prbs = 0x7FF;
1231				break;	// 20~22
1232			case 2:
1233				init_prbs = 0x3D6;
1234				break;	// 23~25
1235			case 3:
1236				init_prbs = 0x53B;
1237				break;	// 26~28
1238			case 4:
1239				init_prbs = 0x213;
1240				break;	// 29~31
1241			case 5:
1242				init_prbs = 0x29;
1243				break;	// 32~34
1244			case 6:
1245				init_prbs = 0xD0;
1246				break;	// 35~37
1247			default:
1248			case 7:
1249				init_prbs = 0x48E;
1250				break;	// 38~40
1251			}
1252			break;
1253
1254		default:
1255		case TRANSMISSION_MODE_8K:
1256			switch (sub_channel) {
1257			case -6:
1258				init_prbs = 0x0;
1259				break;	// 41, 0, 1
1260			case -5:
1261				init_prbs = 0x740;
1262				break;	// 02~04
1263			case -4:
1264				init_prbs = 0x069;
1265				break;	// 05~07
1266			case -3:
1267				init_prbs = 0x7DD;
1268				break;	// 08~10
1269			case -2:
1270				init_prbs = 0x208;
1271				break;	// 11~13
1272			case -1:
1273				init_prbs = 0x7B9;
1274				break;	// 14~16
1275			case 0:
1276				init_prbs = 0x5C7;
1277				break;	// 17~19
1278			case 1:
1279				init_prbs = 0x7FF;
1280				break;	// 20~22
1281			case 2:
1282				init_prbs = 0x53B;
1283				break;	// 23~25
1284			case 3:
1285				init_prbs = 0x29;
1286				break;	// 26~28
1287			case 4:
1288				init_prbs = 0x48E;
1289				break;	// 29~31
1290			case 5:
1291				init_prbs = 0x4C4;
1292				break;	// 32~34
1293			case 6:
1294				init_prbs = 0x367;
1295				break;	// 33~37
1296			default:
1297			case 7:
1298				init_prbs = 0x684;
1299				break;	// 38~40
1300			}
1301			break;
1302		}
1303	} else {
1304		dib8000_write_word(state, 27, (u16) ((state->cfg.pll->ifreq >> 16) & 0x01ff));
1305		dib8000_write_word(state, 28, (u16) (state->cfg.pll->ifreq & 0xffff));
1306		dib8000_write_word(state, 26, (u16) ((state->cfg.pll->ifreq >> 25) & 0x0003));
1307	}
1308	/*P_mode == ?? */
1309	dib8000_write_word(state, 10, (seq << 4));
1310	//  dib8000_write_word(state, 287, (dib8000_read_word(state, 287) & 0xe000) | 0x1000);
1311
1312	switch (state->fe[0]->dtv_property_cache.guard_interval) {
1313	case GUARD_INTERVAL_1_32:
1314		guard = 0;
1315		break;
1316	case GUARD_INTERVAL_1_16:
1317		guard = 1;
1318		break;
1319	case GUARD_INTERVAL_1_8:
1320		guard = 2;
1321		break;
1322	case GUARD_INTERVAL_1_4:
1323	default:
1324		guard = 3;
1325		break;
1326	}
1327
1328	dib8000_write_word(state, 1, (init_prbs << 2) | (guard & 0x3));	// ADDR 1
1329
1330	max_constellation = DQPSK;
1331	for (i = 0; i < 3; i++) {
1332		switch (state->fe[0]->dtv_property_cache.layer[i].modulation) {
1333		case DQPSK:
1334			constellation = 0;
1335			break;
1336		case QPSK:
1337			constellation = 1;
1338			break;
1339		case QAM_16:
1340			constellation = 2;
1341			break;
1342		case QAM_64:
1343		default:
1344			constellation = 3;
1345			break;
1346		}
1347
1348		switch (state->fe[0]->dtv_property_cache.layer[i].fec) {
1349		case FEC_1_2:
1350			crate = 1;
1351			break;
1352		case FEC_2_3:
1353			crate = 2;
1354			break;
1355		case FEC_3_4:
1356			crate = 3;
1357			break;
1358		case FEC_5_6:
1359			crate = 5;
1360			break;
1361		case FEC_7_8:
1362		default:
1363			crate = 7;
1364			break;
1365		}
1366
1367		if ((state->fe[0]->dtv_property_cache.layer[i].interleaving > 0) &&
1368				((state->fe[0]->dtv_property_cache.layer[i].interleaving <= 3) ||
1369				 (state->fe[0]->dtv_property_cache.layer[i].interleaving == 4 && state->fe[0]->dtv_property_cache.isdbt_sb_mode == 1))
1370			)
1371			timeI = state->fe[0]->dtv_property_cache.layer[i].interleaving;
1372		else
1373			timeI = 0;
1374		dib8000_write_word(state, 2 + i, (constellation << 10) | ((state->fe[0]->dtv_property_cache.layer[i].segment_count & 0xf) << 6) |
1375					(crate << 3) | timeI);
1376		if (state->fe[0]->dtv_property_cache.layer[i].segment_count > 0) {
1377			switch (max_constellation) {
1378			case DQPSK:
1379			case QPSK:
1380				if (state->fe[0]->dtv_property_cache.layer[i].modulation == QAM_16 ||
1381					state->fe[0]->dtv_property_cache.layer[i].modulation == QAM_64)
1382					max_constellation = state->fe[0]->dtv_property_cache.layer[i].modulation;
1383				break;
1384			case QAM_16:
1385				if (state->fe[0]->dtv_property_cache.layer[i].modulation == QAM_64)
1386					max_constellation = state->fe[0]->dtv_property_cache.layer[i].modulation;
1387				break;
1388			}
1389		}
1390	}
1391
1392	mode = fft_to_mode(state);
1393
1394	//dib8000_write_word(state, 5, 13); /*p_last_seg = 13*/
1395
1396	dib8000_write_word(state, 274, (dib8000_read_word(state, 274) & 0xffcf) |
1397				((state->fe[0]->dtv_property_cache.isdbt_partial_reception & 1) << 5) | ((state->fe[0]->dtv_property_cache.
1398												 isdbt_sb_mode & 1) << 4));
1399
1400	dprintk("mode = %d ; guard = %d", mode, state->fe[0]->dtv_property_cache.guard_interval);
1401
1402	/* signal optimization parameter */
1403
1404	if (state->fe[0]->dtv_property_cache.isdbt_partial_reception) {
1405		seg_diff_mask = (state->fe[0]->dtv_property_cache.layer[0].modulation == DQPSK) << permu_seg[0];
1406		for (i = 1; i < 3; i++)
1407			nbseg_diff +=
1408				(state->fe[0]->dtv_property_cache.layer[i].modulation == DQPSK) * state->fe[0]->dtv_property_cache.layer[i].segment_count;
1409		for (i = 0; i < nbseg_diff; i++)
1410			seg_diff_mask |= 1 << permu_seg[i + 1];
1411	} else {
1412		for (i = 0; i < 3; i++)
1413			nbseg_diff +=
1414				(state->fe[0]->dtv_property_cache.layer[i].modulation == DQPSK) * state->fe[0]->dtv_property_cache.layer[i].segment_count;
1415		for (i = 0; i < nbseg_diff; i++)
1416			seg_diff_mask |= 1 << permu_seg[i];
1417	}
1418	dprintk("nbseg_diff = %X (%d)", seg_diff_mask, seg_diff_mask);
1419
1420	state->differential_constellation = (seg_diff_mask != 0);
1421	dib8000_set_diversity_in(state->fe[0], state->diversity_onoff);
1422
1423	if (state->fe[0]->dtv_property_cache.isdbt_sb_mode == 1) {
1424		if (state->fe[0]->dtv_property_cache.isdbt_partial_reception == 1)
1425			seg_mask13 = 0x00E0;
1426		else		// 1-segment
1427			seg_mask13 = 0x0040;
1428	} else
1429		seg_mask13 = 0x1fff;
1430
1431	// WRITE: Mode & Diff mask
1432	dib8000_write_word(state, 0, (mode << 13) | seg_diff_mask);
1433
1434	if ((seg_diff_mask) || (state->fe[0]->dtv_property_cache.isdbt_sb_mode))
1435		dib8000_write_word(state, 268, (dib8000_read_word(state, 268) & 0xF9FF) | 0x0200);
1436	else
1437		dib8000_write_word(state, 268, (2 << 9) | 39);	//init value
1438
1439	// ---- SMALL ----
1440	// P_small_seg_diff
1441	dib8000_write_word(state, 352, seg_diff_mask);	// ADDR 352
1442
1443	dib8000_write_word(state, 353, seg_mask13);	// ADDR 353
1444
1445/*	// P_small_narrow_band=0, P_small_last_seg=13, P_small_offset_num_car=5 */
1446
1447	// ---- SMALL ----
1448	if (state->fe[0]->dtv_property_cache.isdbt_sb_mode == 1) {
1449		switch (state->fe[0]->dtv_property_cache.transmission_mode) {
1450		case TRANSMISSION_MODE_2K:
1451			if (state->fe[0]->dtv_property_cache.isdbt_partial_reception == 0) {
1452				if (state->fe[0]->dtv_property_cache.layer[0].modulation == DQPSK)
1453					ncoeff = coeff_2k_sb_1seg_dqpsk;
1454				else	// QPSK or QAM
1455					ncoeff = coeff_2k_sb_1seg;
1456			} else {	// 3-segments
1457				if (state->fe[0]->dtv_property_cache.layer[0].modulation == DQPSK) {
1458					if (state->fe[0]->dtv_property_cache.layer[1].modulation == DQPSK)
1459						ncoeff = coeff_2k_sb_3seg_0dqpsk_1dqpsk;
1460					else	// QPSK or QAM on external segments
1461						ncoeff = coeff_2k_sb_3seg_0dqpsk;
1462				} else {	// QPSK or QAM on central segment
1463					if (state->fe[0]->dtv_property_cache.layer[1].modulation == DQPSK)
1464						ncoeff = coeff_2k_sb_3seg_1dqpsk;
1465					else	// QPSK or QAM on external segments
1466						ncoeff = coeff_2k_sb_3seg;
1467				}
1468			}
1469			break;
1470
1471		case TRANSMISSION_MODE_4K:
1472			if (state->fe[0]->dtv_property_cache.isdbt_partial_reception == 0) {
1473				if (state->fe[0]->dtv_property_cache.layer[0].modulation == DQPSK)
1474					ncoeff = coeff_4k_sb_1seg_dqpsk;
1475				else	// QPSK or QAM
1476					ncoeff = coeff_4k_sb_1seg;
1477			} else {	// 3-segments
1478				if (state->fe[0]->dtv_property_cache.layer[0].modulation == DQPSK) {
1479					if (state->fe[0]->dtv_property_cache.layer[1].modulation == DQPSK) {
1480						ncoeff = coeff_4k_sb_3seg_0dqpsk_1dqpsk;
1481					} else {	// QPSK or QAM on external segments
1482						ncoeff = coeff_4k_sb_3seg_0dqpsk;
1483					}
1484				} else {	// QPSK or QAM on central segment
1485					if (state->fe[0]->dtv_property_cache.layer[1].modulation == DQPSK) {
1486						ncoeff = coeff_4k_sb_3seg_1dqpsk;
1487					} else	// QPSK or QAM on external segments
1488						ncoeff = coeff_4k_sb_3seg;
1489				}
1490			}
1491			break;
1492
1493		case TRANSMISSION_MODE_AUTO:
1494		case TRANSMISSION_MODE_8K:
1495		default:
1496			if (state->fe[0]->dtv_property_cache.isdbt_partial_reception == 0) {
1497				if (state->fe[0]->dtv_property_cache.layer[0].modulation == DQPSK)
1498					ncoeff = coeff_8k_sb_1seg_dqpsk;
1499				else	// QPSK or QAM
1500					ncoeff = coeff_8k_sb_1seg;
1501			} else {	// 3-segments
1502				if (state->fe[0]->dtv_property_cache.layer[0].modulation == DQPSK) {
1503					if (state->fe[0]->dtv_property_cache.layer[1].modulation == DQPSK) {
1504						ncoeff = coeff_8k_sb_3seg_0dqpsk_1dqpsk;
1505					} else {	// QPSK or QAM on external segments
1506						ncoeff = coeff_8k_sb_3seg_0dqpsk;
1507					}
1508				} else {	// QPSK or QAM on central segment
1509					if (state->fe[0]->dtv_property_cache.layer[1].modulation == DQPSK) {
1510						ncoeff = coeff_8k_sb_3seg_1dqpsk;
1511					} else	// QPSK or QAM on external segments
1512						ncoeff = coeff_8k_sb_3seg;
1513				}
1514			}
1515			break;
1516		}
1517		for (i = 0; i < 8; i++)
1518			dib8000_write_word(state, 343 + i, ncoeff[i]);
1519	}
1520
1521	// P_small_coef_ext_enable=ISDB-Tsb, P_small_narrow_band=ISDB-Tsb, P_small_last_seg=13, P_small_offset_num_car=5
1522	dib8000_write_word(state, 351,
1523				(state->fe[0]->dtv_property_cache.isdbt_sb_mode << 9) | (state->fe[0]->dtv_property_cache.isdbt_sb_mode << 8) | (13 << 4) | 5);
1524
1525	// ---- COFF ----
1526	// Carloff, the most robust
1527	if (state->fe[0]->dtv_property_cache.isdbt_sb_mode == 1) {
1528
1529		// P_coff_cpil_alpha=4, P_coff_inh=0, P_coff_cpil_winlen=64
1530		// P_coff_narrow_band=1, P_coff_square_val=1, P_coff_one_seg=~partial_rcpt, P_coff_use_tmcc=1, P_coff_use_ac=1
1531		dib8000_write_word(state, 187,
1532					(4 << 12) | (0 << 11) | (63 << 5) | (0x3 << 3) | ((~state->fe[0]->dtv_property_cache.isdbt_partial_reception & 1) << 2)
1533					| 0x3);
1534
1535/*		// P_small_coef_ext_enable = 1 */
1536/*		dib8000_write_word(state, 351, dib8000_read_word(state, 351) | 0x200); */
1537
1538		if (state->fe[0]->dtv_property_cache.isdbt_partial_reception == 0) {
1539
1540			// P_coff_winlen=63, P_coff_thres_lock=15, P_coff_one_seg_width= (P_mode == 3) , P_coff_one_seg_sym= (P_mode-1)
1541			if (mode == 3)
1542				dib8000_write_word(state, 180, 0x1fcf | ((mode - 1) << 14));
1543			else
1544				dib8000_write_word(state, 180, 0x0fcf | ((mode - 1) << 14));
1545			// P_ctrl_corm_thres4pre_freq_inh=1,P_ctrl_pre_freq_mode_sat=1,
1546			// P_ctrl_pre_freq_inh=0, P_ctrl_pre_freq_step = 5, P_pre_freq_win_len=4
1547			dib8000_write_word(state, 338, (1 << 12) | (1 << 10) | (0 << 9) | (5 << 5) | 4);
1548			// P_ctrl_pre_freq_win_len=16, P_ctrl_pre_freq_thres_lockin=8
1549			dib8000_write_word(state, 340, (16 << 6) | (8 << 0));
1550			// P_ctrl_pre_freq_thres_lockout=6, P_small_use_tmcc/ac/cp=1
1551			dib8000_write_word(state, 341, (6 << 3) | (1 << 2) | (1 << 1) | (1 << 0));
1552
1553			// P_coff_corthres_8k, 4k, 2k and P_coff_cpilthres_8k, 4k, 2k
1554			dib8000_write_word(state, 181, 300);
1555			dib8000_write_word(state, 182, 150);
1556			dib8000_write_word(state, 183, 80);
1557			dib8000_write_word(state, 184, 300);
1558			dib8000_write_word(state, 185, 150);
1559			dib8000_write_word(state, 186, 80);
1560		} else {	// Sound Broadcasting mode 3 seg
1561			// P_coff_one_seg_sym= 1, P_coff_one_seg_width= 1, P_coff_winlen=63, P_coff_thres_lock=15
1562			/*	if (mode == 3) */
1563			/*		dib8000_write_word(state, 180, 0x2fca | ((0) << 14)); */
1564			/*	else */
1565			/*		dib8000_write_word(state, 180, 0x2fca | ((1) << 14)); */
1566			dib8000_write_word(state, 180, 0x1fcf | (1 << 14));
1567
1568			// P_ctrl_corm_thres4pre_freq_inh = 1, P_ctrl_pre_freq_mode_sat=1,
1569			// P_ctrl_pre_freq_inh=0, P_ctrl_pre_freq_step = 4, P_pre_freq_win_len=4
1570			dib8000_write_word(state, 338, (1 << 12) | (1 << 10) | (0 << 9) | (4 << 5) | 4);
1571			// P_ctrl_pre_freq_win_len=16, P_ctrl_pre_freq_thres_lockin=8
1572			dib8000_write_word(state, 340, (16 << 6) | (8 << 0));
1573			//P_ctrl_pre_freq_thres_lockout=6, P_small_use_tmcc/ac/cp=1
1574			dib8000_write_word(state, 341, (6 << 3) | (1 << 2) | (1 << 1) | (1 << 0));
1575
1576			// P_coff_corthres_8k, 4k, 2k and P_coff_cpilthres_8k, 4k, 2k
1577			dib8000_write_word(state, 181, 350);
1578			dib8000_write_word(state, 182, 300);
1579			dib8000_write_word(state, 183, 250);
1580			dib8000_write_word(state, 184, 350);
1581			dib8000_write_word(state, 185, 300);
1582			dib8000_write_word(state, 186, 250);
1583		}
1584
1585	} else if (state->isdbt_cfg_loaded == 0) {	// if not Sound Broadcasting mode : put default values for 13 segments
1586		dib8000_write_word(state, 180, (16 << 6) | 9);
1587		dib8000_write_word(state, 187, (4 << 12) | (8 << 5) | 0x2);
1588		coff_pow = 0x2800;
1589		for (i = 0; i < 6; i++)
1590			dib8000_write_word(state, 181 + i, coff_pow);
1591
1592		// P_ctrl_corm_thres4pre_freq_inh=1, P_ctrl_pre_freq_mode_sat=1,
1593		// P_ctrl_pre_freq_mode_sat=1, P_ctrl_pre_freq_inh=0, P_ctrl_pre_freq_step = 3, P_pre_freq_win_len=1
1594		dib8000_write_word(state, 338, (1 << 12) | (1 << 10) | (0 << 9) | (3 << 5) | 1);
1595
1596		// P_ctrl_pre_freq_win_len=8, P_ctrl_pre_freq_thres_lockin=6
1597		dib8000_write_word(state, 340, (8 << 6) | (6 << 0));
1598		// P_ctrl_pre_freq_thres_lockout=4, P_small_use_tmcc/ac/cp=1
1599		dib8000_write_word(state, 341, (4 << 3) | (1 << 2) | (1 << 1) | (1 << 0));
1600	}
1601	// ---- FFT ----
1602	if (state->fe[0]->dtv_property_cache.isdbt_sb_mode == 1 && state->fe[0]->dtv_property_cache.isdbt_partial_reception == 0)
1603		dib8000_write_word(state, 178, 64);	// P_fft_powrange=64
1604	else
1605		dib8000_write_word(state, 178, 32);	// P_fft_powrange=32
1606
1607	/* make the cpil_coff_lock more robust but slower p_coff_winlen
1608	 * 6bits; p_coff_thres_lock 6bits (for coff lock if needed)
1609	 */
1610	/* if ( ( nbseg_diff>0)&&(nbseg_diff<13))
1611		dib8000_write_word(state, 187, (dib8000_read_word(state, 187) & 0xfffb) | (1 << 3)); */
1612
1613	dib8000_write_word(state, 189, ~seg_mask13 | seg_diff_mask);	/* P_lmod4_seg_inh       */
1614	dib8000_write_word(state, 192, ~seg_mask13 | seg_diff_mask);	/* P_pha3_seg_inh        */
1615	dib8000_write_word(state, 225, ~seg_mask13 | seg_diff_mask);	/* P_tac_seg_inh         */
1616	if ((!state->fe[0]->dtv_property_cache.isdbt_sb_mode) && (state->cfg.pll->ifreq == 0))
1617		dib8000_write_word(state, 266, ~seg_mask13 | seg_diff_mask | 0x40);	/* P_equal_noise_seg_inh */
1618	else
1619		dib8000_write_word(state, 266, ~seg_mask13 | seg_diff_mask);	/* P_equal_noise_seg_inh */
1620	dib8000_write_word(state, 287, ~seg_mask13 | 0x1000);	/* P_tmcc_seg_inh        */
1621	//dib8000_write_word(state, 288, ~seg_mask13 | seg_diff_mask); /* P_tmcc_seg_eq_inh */
1622	if (!autosearching)
1623		dib8000_write_word(state, 288, (~seg_mask13 | seg_diff_mask) & 0x1fff);	/* P_tmcc_seg_eq_inh */
1624	else
1625		dib8000_write_word(state, 288, 0x1fff);	//disable equalisation of the tmcc when autosearch to be able to find the DQPSK channels.
1626	dprintk("287 = %X (%d)", ~seg_mask13 | 0x1000, ~seg_mask13 | 0x1000);
1627
1628	dib8000_write_word(state, 211, seg_mask13 & (~seg_diff_mask));	/* P_des_seg_enabled     */
1629
1630	/* offset loop parameters */
1631	if (state->fe[0]->dtv_property_cache.isdbt_sb_mode == 1) {
1632		if (state->fe[0]->dtv_property_cache.isdbt_partial_reception == 0)
1633			/* P_timf_alpha = (11-P_mode), P_corm_alpha=6, P_corm_thres=0x80 */
1634			dib8000_write_word(state, 32, ((11 - mode) << 12) | (6 << 8) | 0x40);
1635
1636		else		// Sound Broadcasting mode 3 seg
1637			/* P_timf_alpha = (10-P_mode), P_corm_alpha=6, P_corm_thres=0x80 */
1638			dib8000_write_word(state, 32, ((10 - mode) << 12) | (6 << 8) | 0x60);
1639	} else
1640		// TODO in 13 seg, timf_alpha can always be the same or not ?
1641		/* P_timf_alpha = (9-P_mode, P_corm_alpha=6, P_corm_thres=0x80 */
1642		dib8000_write_word(state, 32, ((9 - mode) << 12) | (6 << 8) | 0x80);
1643
1644	if (state->fe[0]->dtv_property_cache.isdbt_sb_mode

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