dib3000mc.c 26.0 KB
Newer Older
L
Linus Torvalds 已提交
1
/*
2
 * Driver for DiBcom DiB3000MC/P-demodulator.
L
Linus Torvalds 已提交
3
 *
4
 * Copyright (C) 2004-7 DiBcom (http://www.dibcom.fr/)
L
Linus Torvalds 已提交
5 6
 * Copyright (C) 2004-5 Patrick Boettcher (patrick.boettcher@desy.de)
 *
7
 * This code is partially based on the previous dib3000mc.c .
L
Linus Torvalds 已提交
8
 *
9
 * This program is free software; you can redistribute it and/or
L
Linus Torvalds 已提交
10 11 12
 *	modify it under the terms of the GNU General Public License as
 *	published by the Free Software Foundation, version 2.
 */
13

L
Linus Torvalds 已提交
14
#include <linux/kernel.h>
15
#include <linux/slab.h>
16 17 18 19 20 21
#include <linux/i2c.h>

#include "dvb_frontend.h"

#include "dib3000mc.h"

L
Linus Torvalds 已提交
22 23
static int debug;
module_param(debug, int, 0644);
24
MODULE_PARM_DESC(debug, "turn on debugging (default: 0)");
L
Linus Torvalds 已提交
25

26 27
static int buggy_sfn_workaround;
module_param(buggy_sfn_workaround, int, 0644);
28
MODULE_PARM_DESC(buggy_sfn_workaround, "Enable work-around for buggy SFNs (default: 0)");
29

30
#define dprintk(args...) do { if (debug) { printk(KERN_DEBUG "DiB3000MC/P:"); printk(args); printk("\n"); } } while (0)
31 32 33 34 35 36 37 38 39 40

struct dib3000mc_state {
	struct dvb_frontend demod;
	struct dib3000mc_config *cfg;

	u8 i2c_addr;
	struct i2c_adapter *i2c_adap;

	struct dibx000_i2c_master i2c_master;

41 42
	u32 timf;

43
	u32 current_bandwidth;
44 45

	u16 dev_id;
46 47

	u8 sfn_workaround_active :1;
48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77
};

static u16 dib3000mc_read_word(struct dib3000mc_state *state, u16 reg)
{
	u8 wb[2] = { (reg >> 8) | 0x80, reg & 0xff };
	u8 rb[2];
	struct i2c_msg msg[2] = {
		{ .addr = state->i2c_addr >> 1, .flags = 0,        .buf = wb, .len = 2 },
		{ .addr = state->i2c_addr >> 1, .flags = I2C_M_RD, .buf = rb, .len = 2 },
	};

	if (i2c_transfer(state->i2c_adap, msg, 2) != 2)
		dprintk("i2c read error on %d\n",reg);

	return (rb[0] << 8) | rb[1];
}

static int dib3000mc_write_word(struct dib3000mc_state *state, u16 reg, u16 val)
{
	u8 b[4] = {
		(reg >> 8) & 0xff, reg & 0xff,
		(val >> 8) & 0xff, val & 0xff,
	};
	struct i2c_msg msg = {
		.addr = state->i2c_addr >> 1, .flags = 0, .buf = b, .len = 4
	};
	return i2c_transfer(state->i2c_adap, &msg, 1) != 1 ? -EREMOTEIO : 0;
}

static int dib3000mc_identify(struct dib3000mc_state *state)
L
Linus Torvalds 已提交
78
{
79 80 81 82 83
	u16 value;
	if ((value = dib3000mc_read_word(state, 1025)) != 0x01b3) {
		dprintk("-E-  DiB3000MC/P: wrong Vendor ID (read=0x%x)\n",value);
		return -EREMOTEIO;
	}
L
Linus Torvalds 已提交
84

85 86 87 88
	value = dib3000mc_read_word(state, 1026);
	if (value != 0x3001 && value != 0x3002) {
		dprintk("-E-  DiB3000MC/P: wrong Device ID (%x)\n",value);
		return -EREMOTEIO;
L
Linus Torvalds 已提交
89
	}
90 91 92 93 94 95 96
	state->dev_id = value;

	dprintk("-I-  found DiB3000MC/P: %x\n",state->dev_id);

	return 0;
}

97
static int dib3000mc_set_timing(struct dib3000mc_state *state, s16 nfft, u32 bw, u8 update_offset)
98
{
99
	u32 timf;
100

101 102 103 104
	if (state->timf == 0) {
		timf = 1384402; // default value for 8MHz
		if (update_offset)
			msleep(200); // first time we do an update
L
Linus Torvalds 已提交
105
	} else
106
		timf = state->timf;
L
Linus Torvalds 已提交
107

108
	timf *= (bw / 1000);
L
Linus Torvalds 已提交
109

110 111 112 113 114 115
	if (update_offset) {
		s16 tim_offs = dib3000mc_read_word(state, 416);

		if (tim_offs &  0x2000)
			tim_offs -= 0x4000;

116
		if (nfft == TRANSMISSION_MODE_2K)
117 118 119
			tim_offs *= 4;

		timf += tim_offs;
120
		state->timf = timf / (bw / 1000);
121
	}
122

123
	dprintk("timf: %d\n", timf);
L
Linus Torvalds 已提交
124

125 126
	dib3000mc_write_word(state, 23, (u16) (timf >> 16));
	dib3000mc_write_word(state, 24, (u16) (timf      ) & 0xffff);
L
Linus Torvalds 已提交
127 128 129 130

	return 0;
}

131
static int dib3000mc_setup_pwm_state(struct dib3000mc_state *state)
L
Linus Torvalds 已提交
132
{
133
	u16 reg_51, reg_52 = state->cfg->agc->setup & 0xfefb;
134
    if (state->cfg->pwm3_inversion) {
135 136
		reg_51 =  (2 << 14) | (0 << 10) | (7 << 6) | (2 << 2) | (2 << 0);
		reg_52 |= (1 << 2);
L
Linus Torvalds 已提交
137
	} else {
138 139
		reg_51 = (2 << 14) | (4 << 10) | (7 << 6) | (2 << 2) | (2 << 0);
		reg_52 |= (1 << 8);
L
Linus Torvalds 已提交
140
	}
141 142
	dib3000mc_write_word(state, 51, reg_51);
	dib3000mc_write_word(state, 52, reg_52);
143 144 145 146 147 148 149

    if (state->cfg->use_pwm3)
		dib3000mc_write_word(state, 245, (1 << 3) | (1 << 0));
	else
		dib3000mc_write_word(state, 245, 0);

    dib3000mc_write_word(state, 1040, 0x3);
L
Linus Torvalds 已提交
150 151 152
	return 0;
}

153
static int dib3000mc_set_output_mode(struct dib3000mc_state *state, int mode)
L
Linus Torvalds 已提交
154
{
155 156 157 158 159
	int    ret = 0;
	u16 fifo_threshold = 1792;
	u16 outreg = 0;
	u16 outmode = 0;
	u16 elecout = 1;
160
	u16 smo_reg = dib3000mc_read_word(state, 206) & 0x0010; /* keep the pid_parse bit */
161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187

	dprintk("-I-  Setting output mode for demod %p to %d\n",
			&state->demod, mode);

	switch (mode) {
		case OUTMODE_HIGH_Z:  // disable
			elecout = 0;
			break;
		case OUTMODE_MPEG2_PAR_GATED_CLK:   // STBs with parallel gated clock
			outmode = 0;
			break;
		case OUTMODE_MPEG2_PAR_CONT_CLK:    // STBs with parallel continues clock
			outmode = 1;
			break;
		case OUTMODE_MPEG2_SERIAL:          // STBs with serial input
			outmode = 2;
			break;
		case OUTMODE_MPEG2_FIFO:            // e.g. USB feeding
			elecout = 3;
			/*ADDR @ 206 :
			P_smo_error_discard  [1;6:6] = 0
			P_smo_rs_discard     [1;5:5] = 0
			P_smo_pid_parse      [1;4:4] = 0
			P_smo_fifo_flush     [1;3:3] = 0
			P_smo_mode           [2;2:1] = 11
			P_smo_ovf_prot       [1;0:0] = 0
			*/
188
			smo_reg |= 3 << 1;
189 190 191 192 193 194
			fifo_threshold = 512;
			outmode = 5;
			break;
		case OUTMODE_DIVERSITY:
			outmode = 4;
			elecout = 1;
L
Linus Torvalds 已提交
195 196
			break;
		default:
197 198
			dprintk("Unhandled output_mode passed to be set for demod %p\n",&state->demod);
			outmode = 0;
L
Linus Torvalds 已提交
199 200
			break;
	}
201 202

	if ((state->cfg->output_mpeg2_in_188_bytes))
203
		smo_reg |= (1 << 5); // P_smo_rs_discard     [1;5:5] = 1
204 205 206 207 208 209 210 211

	outreg = dib3000mc_read_word(state, 244) & 0x07FF;
	outreg |= (outmode << 11);
	ret |= dib3000mc_write_word(state,  244, outreg);
	ret |= dib3000mc_write_word(state,  206, smo_reg);   /*smo_ mode*/
	ret |= dib3000mc_write_word(state,  207, fifo_threshold); /* synchronous fread */
	ret |= dib3000mc_write_word(state, 1040, elecout);         /* P_out_cfg */
	return ret;
L
Linus Torvalds 已提交
212 213
}

214
static int dib3000mc_set_bandwidth(struct dib3000mc_state *state, u32 bw)
L
Linus Torvalds 已提交
215
{
216 217 218
	u16 bw_cfg[6] = { 0 };
	u16 imp_bw_cfg[3] = { 0 };
	u16 reg;
L
Linus Torvalds 已提交
219

220 221
/* settings here are for 27.7MHz */
	switch (bw) {
222
		case 8000:
223 224 225
			bw_cfg[0] = 0x0019; bw_cfg[1] = 0x5c30; bw_cfg[2] = 0x0054; bw_cfg[3] = 0x88a0; bw_cfg[4] = 0x01a6; bw_cfg[5] = 0xab20;
			imp_bw_cfg[0] = 0x04db; imp_bw_cfg[1] = 0x00db; imp_bw_cfg[2] = 0x00b7;
			break;
L
Linus Torvalds 已提交
226

227
		case 7000:
228 229 230
			bw_cfg[0] = 0x001c; bw_cfg[1] = 0xfba5; bw_cfg[2] = 0x0060; bw_cfg[3] = 0x9c25; bw_cfg[4] = 0x01e3; bw_cfg[5] = 0x0cb7;
			imp_bw_cfg[0] = 0x04c0; imp_bw_cfg[1] = 0x00c0; imp_bw_cfg[2] = 0x00a0;
			break;
L
Linus Torvalds 已提交
231

232
		case 6000:
233 234
			bw_cfg[0] = 0x0021; bw_cfg[1] = 0xd040; bw_cfg[2] = 0x0070; bw_cfg[3] = 0xb62b; bw_cfg[4] = 0x0233; bw_cfg[5] = 0x8ed5;
			imp_bw_cfg[0] = 0x04a5; imp_bw_cfg[1] = 0x00a5; imp_bw_cfg[2] = 0x0089;
L
Linus Torvalds 已提交
235
			break;
236

237
		case 5000:
238 239
			bw_cfg[0] = 0x0028; bw_cfg[1] = 0x9380; bw_cfg[2] = 0x0087; bw_cfg[3] = 0x4100; bw_cfg[4] = 0x02a4; bw_cfg[5] = 0x4500;
			imp_bw_cfg[0] = 0x0489; imp_bw_cfg[1] = 0x0089; imp_bw_cfg[2] = 0x0072;
L
Linus Torvalds 已提交
240
			break;
241 242

		default: return -EINVAL;
L
Linus Torvalds 已提交
243 244
	}

245 246 247 248 249 250 251 252 253 254 255
	for (reg = 6; reg < 12; reg++)
		dib3000mc_write_word(state, reg, bw_cfg[reg - 6]);
	dib3000mc_write_word(state, 12, 0x0000);
	dib3000mc_write_word(state, 13, 0x03e8);
	dib3000mc_write_word(state, 14, 0x0000);
	dib3000mc_write_word(state, 15, 0x03f2);
	dib3000mc_write_word(state, 16, 0x0001);
	dib3000mc_write_word(state, 17, 0xb0d0);
	// P_sec_len
	dib3000mc_write_word(state, 18, 0x0393);
	dib3000mc_write_word(state, 19, 0x8700);
L
Linus Torvalds 已提交
256

257 258
	for (reg = 55; reg < 58; reg++)
		dib3000mc_write_word(state, reg, imp_bw_cfg[reg - 55]);
L
Linus Torvalds 已提交
259

260
	// Timing configuration
261
	dib3000mc_set_timing(state, TRANSMISSION_MODE_2K, bw, 0);
L
Linus Torvalds 已提交
262

263 264
	return 0;
}
L
Linus Torvalds 已提交
265

266
static u16 impulse_noise_val[29] =
L
Linus Torvalds 已提交
267

268 269 270 271 272
{
	0x38, 0x6d9, 0x3f28, 0x7a7, 0x3a74, 0x196, 0x32a, 0x48c, 0x3ffe, 0x7f3,
	0x2d94, 0x76, 0x53d, 0x3ff8, 0x7e3, 0x3320, 0x76, 0x5b3, 0x3feb, 0x7d2,
	0x365e, 0x76, 0x48c, 0x3ffe, 0x5b3, 0x3feb, 0x76, 0x0000, 0xd
};
L
Linus Torvalds 已提交
273

274 275 276 277 278 279
static void dib3000mc_set_impulse_noise(struct dib3000mc_state *state, u8 mode, s16 nfft)
{
	u16 i;
	for (i = 58; i < 87; i++)
		dib3000mc_write_word(state, i, impulse_noise_val[i-58]);

280
	if (nfft == TRANSMISSION_MODE_8K) {
281 282 283
		dib3000mc_write_word(state, 58, 0x3b);
		dib3000mc_write_word(state, 84, 0x00);
		dib3000mc_write_word(state, 85, 0x8200);
L
Linus Torvalds 已提交
284 285
	}

286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309
	dib3000mc_write_word(state, 34, 0x1294);
	dib3000mc_write_word(state, 35, 0x1ff8);
	if (mode == 1)
		dib3000mc_write_word(state, 55, dib3000mc_read_word(state, 55) | (1 << 10));
}

static int dib3000mc_init(struct dvb_frontend *demod)
{
	struct dib3000mc_state *state = demod->demodulator_priv;
	struct dibx000_agc_config *agc = state->cfg->agc;

	// Restart Configuration
	dib3000mc_write_word(state, 1027, 0x8000);
	dib3000mc_write_word(state, 1027, 0x0000);

	// power up the demod + mobility configuration
	dib3000mc_write_word(state, 140, 0x0000);
	dib3000mc_write_word(state, 1031, 0);

	if (state->cfg->mobile_mode) {
		dib3000mc_write_word(state, 139,  0x0000);
		dib3000mc_write_word(state, 141,  0x0000);
		dib3000mc_write_word(state, 175,  0x0002);
		dib3000mc_write_word(state, 1032, 0x0000);
L
Linus Torvalds 已提交
310
	} else {
311 312 313 314
		dib3000mc_write_word(state, 139,  0x0001);
		dib3000mc_write_word(state, 141,  0x0000);
		dib3000mc_write_word(state, 175,  0x0000);
		dib3000mc_write_word(state, 1032, 0x012C);
L
Linus Torvalds 已提交
315
	}
316
	dib3000mc_write_word(state, 1033, 0x0000);
L
Linus Torvalds 已提交
317

318
	// P_clk_cfg
319
	dib3000mc_write_word(state, 1037, 0x3130);
L
Linus Torvalds 已提交
320

321
	// other configurations
L
Linus Torvalds 已提交
322

323 324 325
	// P_ctrl_sfreq
	dib3000mc_write_word(state, 33, (5 << 0));
	dib3000mc_write_word(state, 88, (1 << 10) | (0x10 << 0));
L
Linus Torvalds 已提交
326

327 328 329
	// Phase noise control
	// P_fft_phacor_inh, P_fft_phacor_cpe, P_fft_powrange
	dib3000mc_write_word(state, 99, (1 << 9) | (0x20 << 0));
L
Linus Torvalds 已提交
330

331 332 333 334 335 336 337 338 339
	if (state->cfg->phase_noise_mode == 0)
		dib3000mc_write_word(state, 111, 0x00);
	else
		dib3000mc_write_word(state, 111, 0x02);

	// P_agc_global
	dib3000mc_write_word(state, 50, 0x8000);

	// agc setup misc
340
	dib3000mc_setup_pwm_state(state);
341 342 343 344 345 346 347 348

	// P_agc_counter_lock
	dib3000mc_write_word(state, 53, 0x87);
	// P_agc_counter_unlock
	dib3000mc_write_word(state, 54, 0x87);

	/* agc */
	dib3000mc_write_word(state, 36, state->cfg->max_time);
349
	dib3000mc_write_word(state, 37, (state->cfg->agc_command1 << 13) | (state->cfg->agc_command2 << 12) | (0x1d << 0));
350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379
	dib3000mc_write_word(state, 38, state->cfg->pwm3_value);
	dib3000mc_write_word(state, 39, state->cfg->ln_adc_level);

	// set_agc_loop_Bw
	dib3000mc_write_word(state, 40, 0x0179);
	dib3000mc_write_word(state, 41, 0x03f0);

	dib3000mc_write_word(state, 42, agc->agc1_max);
	dib3000mc_write_word(state, 43, agc->agc1_min);
	dib3000mc_write_word(state, 44, agc->agc2_max);
	dib3000mc_write_word(state, 45, agc->agc2_min);
	dib3000mc_write_word(state, 46, (agc->agc1_pt1 << 8) | agc->agc1_pt2);
	dib3000mc_write_word(state, 47, (agc->agc1_slope1 << 8) | agc->agc1_slope2);
	dib3000mc_write_word(state, 48, (agc->agc2_pt1 << 8) | agc->agc2_pt2);
	dib3000mc_write_word(state, 49, (agc->agc2_slope1 << 8) | agc->agc2_slope2);

// Begin: TimeOut registers
	// P_pha3_thres
	dib3000mc_write_word(state, 110, 3277);
	// P_timf_alpha = 6, P_corm_alpha = 6, P_corm_thres = 0x80
	dib3000mc_write_word(state,  26, 0x6680);
	// lock_mask0
	dib3000mc_write_word(state, 1, 4);
	// lock_mask1
	dib3000mc_write_word(state, 2, 4);
	// lock_mask2
	dib3000mc_write_word(state, 3, 0x1000);
	// P_search_maxtrial=1
	dib3000mc_write_word(state, 5, 1);

380
	dib3000mc_set_bandwidth(state, 8000);
381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400

	// div_lock_mask
	dib3000mc_write_word(state,  4, 0x814);

	dib3000mc_write_word(state, 21, (1 << 9) | 0x164);
	dib3000mc_write_word(state, 22, 0x463d);

	// Spurious rm cfg
	// P_cspu_regul, P_cspu_win_cut
	dib3000mc_write_word(state, 120, 0x200f);
	// P_adp_selec_monit
	dib3000mc_write_word(state, 134, 0);

	// Fec cfg
	dib3000mc_write_word(state, 195, 0x10);

	// diversity register: P_dvsy_sync_wait..
	dib3000mc_write_word(state, 180, 0x2FF0);

	// Impulse noise configuration
401
	dib3000mc_set_impulse_noise(state, 0, TRANSMISSION_MODE_8K);
402 403 404 405 406 407

	// output mode set-up
	dib3000mc_set_output_mode(state, OUTMODE_HIGH_Z);

	/* close the i2c-gate */
	dib3000mc_write_word(state, 769, (1 << 7) );
L
Linus Torvalds 已提交
408

409 410
	return 0;
}
L
Linus Torvalds 已提交
411

412 413 414
static int dib3000mc_sleep(struct dvb_frontend *demod)
{
	struct dib3000mc_state *state = demod->demodulator_priv;
L
Linus Torvalds 已提交
415

416 417
	dib3000mc_write_word(state, 1031, 0xFFFF);
	dib3000mc_write_word(state, 1032, 0xFFFF);
418
	dib3000mc_write_word(state, 1033, 0xFFF0);
L
Linus Torvalds 已提交
419

420 421
    return 0;
}
L
Linus Torvalds 已提交
422

423 424 425 426
static void dib3000mc_set_adp_cfg(struct dib3000mc_state *state, s16 qam)
{
	u16 cfg[4] = { 0 },reg;
	switch (qam) {
427
		case QPSK:
428 429
			cfg[0] = 0x099a; cfg[1] = 0x7fae; cfg[2] = 0x0333; cfg[3] = 0x7ff0;
			break;
430
		case QAM_16:
431 432
			cfg[0] = 0x023d; cfg[1] = 0x7fdf; cfg[2] = 0x00a4; cfg[3] = 0x7ff0;
			break;
433
		case QAM_64:
434 435
			cfg[0] = 0x0148; cfg[1] = 0x7ff0; cfg[2] = 0x00a4; cfg[3] = 0x7ff8;
			break;
L
Linus Torvalds 已提交
436
	}
437 438
	for (reg = 129; reg < 133; reg++)
		dib3000mc_write_word(state, reg, cfg[reg - 129]);
L
Linus Torvalds 已提交
439 440
}

441 442
static void dib3000mc_set_channel_cfg(struct dib3000mc_state *state,
				      struct dtv_frontend_properties *ch, u16 seq)
L
Linus Torvalds 已提交
443
{
444
	u16 value;
445 446 447 448
	u32 bw = BANDWIDTH_TO_KHZ(ch->bandwidth_hz);

	dib3000mc_set_bandwidth(state, bw);
	dib3000mc_set_timing(state, ch->transmission_mode, bw, 0);
L
Linus Torvalds 已提交
449

450 451 452 453
//	if (boost)
//		dib3000mc_write_word(state, 100, (11 << 6) + 6);
//	else
		dib3000mc_write_word(state, 100, (16 << 6) + 9);
L
Linus Torvalds 已提交
454

455 456
	dib3000mc_write_word(state, 1027, 0x0800);
	dib3000mc_write_word(state, 1027, 0x0000);
L
Linus Torvalds 已提交
457

458 459 460 461
	//Default cfg isi offset adp
	dib3000mc_write_word(state, 26,  0x6680);
	dib3000mc_write_word(state, 29,  0x1273);
	dib3000mc_write_word(state, 33,       5);
462
	dib3000mc_set_adp_cfg(state, QAM_16);
463
	dib3000mc_write_word(state, 133,  15564);
L
Linus Torvalds 已提交
464

465 466 467 468
	dib3000mc_write_word(state, 12 , 0x0);
	dib3000mc_write_word(state, 13 , 0x3e8);
	dib3000mc_write_word(state, 14 , 0x0);
	dib3000mc_write_word(state, 15 , 0x3f2);
L
Linus Torvalds 已提交
469

470 471 472 473 474 475
	dib3000mc_write_word(state, 93,0);
	dib3000mc_write_word(state, 94,0);
	dib3000mc_write_word(state, 95,0);
	dib3000mc_write_word(state, 96,0);
	dib3000mc_write_word(state, 97,0);
	dib3000mc_write_word(state, 98,0);
L
Linus Torvalds 已提交
476

477
	dib3000mc_set_impulse_noise(state, 0, ch->transmission_mode);
478

479
	value = 0;
480
	switch (ch->transmission_mode) {
481 482 483 484
		case TRANSMISSION_MODE_2K: value |= (0 << 7); break;
		default:
		case TRANSMISSION_MODE_8K: value |= (1 << 7); break;
	}
485
	switch (ch->guard_interval) {
486 487 488 489 490 491
		case GUARD_INTERVAL_1_32: value |= (0 << 5); break;
		case GUARD_INTERVAL_1_16: value |= (1 << 5); break;
		case GUARD_INTERVAL_1_4:  value |= (3 << 5); break;
		default:
		case GUARD_INTERVAL_1_8:  value |= (2 << 5); break;
	}
492
	switch (ch->modulation) {
493 494 495 496 497 498 499 500 501 502 503 504
		case QPSK:  value |= (0 << 3); break;
		case QAM_16: value |= (1 << 3); break;
		default:
		case QAM_64: value |= (2 << 3); break;
	}
	switch (HIERARCHY_1) {
		case HIERARCHY_2: value |= 2; break;
		case HIERARCHY_4: value |= 4; break;
		default:
		case HIERARCHY_1: value |= 1; break;
	}
	dib3000mc_write_word(state, 0, value);
505
	dib3000mc_write_word(state, 5, (1 << 8) | ((seq & 0xf) << 4));
L
Linus Torvalds 已提交
506

507
	value = 0;
508
	if (ch->hierarchy == 1)
509 510 511
		value |= (1 << 4);
	if (1 == 1)
		value |= 1;
512
	switch ((ch->hierarchy == 0 || 1 == 1) ? ch->code_rate_HP : ch->code_rate_LP) {
513 514 515 516 517 518 519 520
		case FEC_2_3: value |= (2 << 1); break;
		case FEC_3_4: value |= (3 << 1); break;
		case FEC_5_6: value |= (5 << 1); break;
		case FEC_7_8: value |= (7 << 1); break;
		default:
		case FEC_1_2: value |= (1 << 1); break;
	}
	dib3000mc_write_word(state, 181, value);
L
Linus Torvalds 已提交
521

522
	// diversity synchro delay add 50% SFN margin
523
	switch (ch->transmission_mode) {
524 525 526 527
		case TRANSMISSION_MODE_8K: value = 256; break;
		case TRANSMISSION_MODE_2K:
		default: value = 64; break;
	}
528
	switch (ch->guard_interval) {
529 530 531 532 533 534 535 536 537
		case GUARD_INTERVAL_1_16: value *= 2; break;
		case GUARD_INTERVAL_1_8:  value *= 4; break;
		case GUARD_INTERVAL_1_4:  value *= 8; break;
		default:
		case GUARD_INTERVAL_1_32: value *= 1; break;
	}
	value <<= 4;
	value |= dib3000mc_read_word(state, 180) & 0x000f;
	dib3000mc_write_word(state, 180, value);
L
Linus Torvalds 已提交
538

539
	// restart demod
540 541 542
	value = dib3000mc_read_word(state, 0);
	dib3000mc_write_word(state, 0, value | (1 << 9));
	dib3000mc_write_word(state, 0, value);
L
Linus Torvalds 已提交
543

544
	msleep(30);
L
Linus Torvalds 已提交
545

546
	dib3000mc_set_impulse_noise(state, state->cfg->impulse_noise_mode, ch->transmission_mode);
547
}
L
Linus Torvalds 已提交
548

549
static int dib3000mc_autosearch_start(struct dvb_frontend *demod)
550
{
551
	struct dtv_frontend_properties *chan = &demod->dtv_property_cache;
552 553 554
	struct dib3000mc_state *state = demod->demodulator_priv;
	u16 reg;
//	u32 val;
555
	struct dtv_frontend_properties schan;
L
Linus Torvalds 已提交
556

557
	schan = *chan;
L
Linus Torvalds 已提交
558

559
	/* TODO what is that ? */
L
Linus Torvalds 已提交
560

561
	/* a channel for autosearch */
562 563 564 565 566 567
	schan.transmission_mode = TRANSMISSION_MODE_8K;
	schan.guard_interval = GUARD_INTERVAL_1_32;
	schan.modulation = QAM_64;
	schan.code_rate_HP = FEC_2_3;
	schan.code_rate_LP = FEC_2_3;
	schan.hierarchy = 0;
L
Linus Torvalds 已提交
568

569
	dib3000mc_set_channel_cfg(state, &schan, 11);
L
Linus Torvalds 已提交
570

571 572
	reg = dib3000mc_read_word(state, 0);
	dib3000mc_write_word(state, 0, reg | (1 << 8));
573
	dib3000mc_read_word(state, 511);
574
	dib3000mc_write_word(state, 0, reg);
L
Linus Torvalds 已提交
575

576 577
	return 0;
}
L
Linus Torvalds 已提交
578

579 580 581 582
static int dib3000mc_autosearch_is_irq(struct dvb_frontend *demod)
{
	struct dib3000mc_state *state = demod->demodulator_priv;
	u16 irq_pending = dib3000mc_read_word(state, 511);
L
Linus Torvalds 已提交
583

584 585
	if (irq_pending & 0x1) // failed
		return 1;
L
Linus Torvalds 已提交
586

587 588
	if (irq_pending & 0x2) // succeeded
		return 2;
589

590
	return 0; // still pending
L
Linus Torvalds 已提交
591
}
592

593
static int dib3000mc_tune(struct dvb_frontend *demod)
L
Linus Torvalds 已提交
594
{
595
	struct dtv_frontend_properties *ch = &demod->dtv_property_cache;
596
	struct dib3000mc_state *state = demod->demodulator_priv;
L
Linus Torvalds 已提交
597

598 599 600 601
	// ** configure demod **
	dib3000mc_set_channel_cfg(state, ch, 0);

	// activates isi
602 603 604 605 606 607 608 609
	if (state->sfn_workaround_active) {
		dprintk("SFN workaround is active\n");
		dib3000mc_write_word(state, 29, 0x1273);
		dib3000mc_write_word(state, 108, 0x4000); // P_pha3_force_pha_shift
	} else {
		dib3000mc_write_word(state, 29, 0x1073);
		dib3000mc_write_word(state, 108, 0x0000); // P_pha3_force_pha_shift
	}
L
Linus Torvalds 已提交
610

611 612
	dib3000mc_set_adp_cfg(state, (u8)ch->modulation);
	if (ch->transmission_mode == TRANSMISSION_MODE_8K) {
613 614 615 616 617 618 619
		dib3000mc_write_word(state, 26, 38528);
		dib3000mc_write_word(state, 33, 8);
	} else {
		dib3000mc_write_word(state, 26, 30336);
		dib3000mc_write_word(state, 33, 6);
	}

620
	if (dib3000mc_read_word(state, 509) & 0x80)
621 622
		dib3000mc_set_timing(state, ch->transmission_mode,
				     BANDWIDTH_TO_KHZ(ch->bandwidth_hz), 1);
L
Linus Torvalds 已提交
623 624 625 626

	return 0;
}

627
struct i2c_adapter * dib3000mc_get_tuner_i2c_master(struct dvb_frontend *demod, int gating)
L
Linus Torvalds 已提交
628
{
629 630
	struct dib3000mc_state *st = demod->demodulator_priv;
	return dibx000_get_i2c_adapter(&st->i2c_master, DIBX000_I2C_INTERFACE_TUNER, gating);
L
Linus Torvalds 已提交
631 632
}

633 634
EXPORT_SYMBOL(dib3000mc_get_tuner_i2c_master);

635
static int dib3000mc_get_frontend(struct dvb_frontend* fe)
L
Linus Torvalds 已提交
636
{
637
	struct dtv_frontend_properties *fep = &fe->dtv_property_cache;
638 639
	struct dib3000mc_state *state = fe->demodulator_priv;
	u16 tps = dib3000mc_read_word(state,458);
L
Linus Torvalds 已提交
640

641 642
	fep->inversion = INVERSION_AUTO;

643
	fep->bandwidth_hz = state->current_bandwidth;
644 645

	switch ((tps >> 8) & 0x1) {
646 647
		case 0: fep->transmission_mode = TRANSMISSION_MODE_2K; break;
		case 1: fep->transmission_mode = TRANSMISSION_MODE_8K; break;
648 649 650
	}

	switch (tps & 0x3) {
651 652 653 654
		case 0: fep->guard_interval = GUARD_INTERVAL_1_32; break;
		case 1: fep->guard_interval = GUARD_INTERVAL_1_16; break;
		case 2: fep->guard_interval = GUARD_INTERVAL_1_8; break;
		case 3: fep->guard_interval = GUARD_INTERVAL_1_4; break;
655 656 657
	}

	switch ((tps >> 13) & 0x3) {
658 659
		case 0: fep->modulation = QPSK; break;
		case 1: fep->modulation = QAM_16; break;
660
		case 2:
661
		default: fep->modulation = QAM_64; break;
662 663 664 665 666
	}

	/* as long as the frontend_param structure is fixed for hierarchical transmission I refuse to use it */
	/* (tps >> 12) & 0x1 == hrch is used, (tps >> 9) & 0x7 == alpha */

667
	fep->hierarchy = HIERARCHY_NONE;
668
	switch ((tps >> 5) & 0x7) {
669 670 671 672
		case 1: fep->code_rate_HP = FEC_1_2; break;
		case 2: fep->code_rate_HP = FEC_2_3; break;
		case 3: fep->code_rate_HP = FEC_3_4; break;
		case 5: fep->code_rate_HP = FEC_5_6; break;
673
		case 7:
674
		default: fep->code_rate_HP = FEC_7_8; break;
675 676 677 678

	}

	switch ((tps >> 2) & 0x7) {
679 680 681 682
		case 1: fep->code_rate_LP = FEC_1_2; break;
		case 2: fep->code_rate_LP = FEC_2_3; break;
		case 3: fep->code_rate_LP = FEC_3_4; break;
		case 5: fep->code_rate_LP = FEC_5_6; break;
683
		case 7:
684
		default: fep->code_rate_LP = FEC_7_8; break;
685
	}
L
Linus Torvalds 已提交
686 687 688 689

	return 0;
}

690
static int dib3000mc_set_frontend(struct dvb_frontend *fe)
L
Linus Torvalds 已提交
691
{
692
	struct dtv_frontend_properties *fep = &fe->dtv_property_cache;
693
	struct dib3000mc_state *state = fe->demodulator_priv;
694
	int ret;
695 696

	dib3000mc_set_output_mode(state, OUTMODE_HIGH_Z);
697

698 699
	state->current_bandwidth = fep->bandwidth_hz;
	dib3000mc_set_bandwidth(state, BANDWIDTH_TO_KHZ(fep->bandwidth_hz));
700

701 702 703
	/* maybe the parameter has been changed */
	state->sfn_workaround_active = buggy_sfn_workaround;

704
	if (fe->ops.tuner_ops.set_params) {
705
		fe->ops.tuner_ops.set_params(fe);
706 707 708
		msleep(100);
	}

709 710 711 712
	if (fep->transmission_mode  == TRANSMISSION_MODE_AUTO ||
	    fep->guard_interval == GUARD_INTERVAL_AUTO ||
	    fep->modulation     == QAM_AUTO ||
	    fep->code_rate_HP   == FEC_AUTO) {
713
		int i = 1000, found;
714

715
		dib3000mc_autosearch_start(fe);
716 717 718 719 720 721 722 723 724
		do {
			msleep(1);
			found = dib3000mc_autosearch_is_irq(fe);
		} while (found == 0 && i--);

		dprintk("autosearch returns: %d\n",found);
		if (found == 0 || found == 1)
			return 0; // no channel found

725
		dib3000mc_get_frontend(fe);
726 727
	}

728
	ret = dib3000mc_tune(fe);
729

730 731
	/* make this a config parameter */
	dib3000mc_set_output_mode(state, OUTMODE_MPEG2_FIFO);
732
	return ret;
L
Linus Torvalds 已提交
733 734
}

735
static int dib3000mc_read_status(struct dvb_frontend *fe, fe_status_t *stat)
L
Linus Torvalds 已提交
736
{
737 738 739 740 741 742 743 744 745 746 747 748 749 750 751 752
	struct dib3000mc_state *state = fe->demodulator_priv;
	u16 lock = dib3000mc_read_word(state, 509);

	*stat = 0;

	if (lock & 0x8000)
		*stat |= FE_HAS_SIGNAL;
	if (lock & 0x3000)
		*stat |= FE_HAS_CARRIER;
	if (lock & 0x0100)
		*stat |= FE_HAS_VITERBI;
	if (lock & 0x0010)
		*stat |= FE_HAS_SYNC;
	if (lock & 0x0008)
		*stat |= FE_HAS_LOCK;

L
Linus Torvalds 已提交
753 754 755
	return 0;
}

756
static int dib3000mc_read_ber(struct dvb_frontend *fe, u32 *ber)
L
Linus Torvalds 已提交
757
{
758 759 760
	struct dib3000mc_state *state = fe->demodulator_priv;
	*ber = (dib3000mc_read_word(state, 500) << 16) | dib3000mc_read_word(state, 501);
	return 0;
L
Linus Torvalds 已提交
761 762
}

763
static int dib3000mc_read_unc_blocks(struct dvb_frontend *fe, u32 *unc)
L
Linus Torvalds 已提交
764
{
765 766 767
	struct dib3000mc_state *state = fe->demodulator_priv;
	*unc = dib3000mc_read_word(state, 508);
	return 0;
L
Linus Torvalds 已提交
768 769
}

770
static int dib3000mc_read_signal_strength(struct dvb_frontend *fe, u16 *strength)
L
Linus Torvalds 已提交
771
{
772 773 774 775
	struct dib3000mc_state *state = fe->demodulator_priv;
	u16 val = dib3000mc_read_word(state, 392);
	*strength = 65535 - val;
	return 0;
L
Linus Torvalds 已提交
776 777
}

778
static int dib3000mc_read_snr(struct dvb_frontend* fe, u16 *snr)
L
Linus Torvalds 已提交
779
{
780
	*snr = 0x0000;
L
Linus Torvalds 已提交
781 782 783
	return 0;
}

784
static int dib3000mc_fe_get_tune_settings(struct dvb_frontend* fe, struct dvb_frontend_tune_settings *tune)
L
Linus Torvalds 已提交
785
{
786
	tune->min_delay_ms = 1000;
L
Linus Torvalds 已提交
787 788 789
	return 0;
}

790
static void dib3000mc_release(struct dvb_frontend *fe)
L
Linus Torvalds 已提交
791
{
792 793 794
	struct dib3000mc_state *state = fe->demodulator_priv;
	dibx000_exit_i2c_master(&state->i2c_master);
	kfree(state);
L
Linus Torvalds 已提交
795 796
}

797
int dib3000mc_pid_control(struct dvb_frontend *fe, int index, int pid,int onoff)
L
Linus Torvalds 已提交
798
{
799 800
	struct dib3000mc_state *state = fe->demodulator_priv;
	dib3000mc_write_word(state, 212 + index,  onoff ? (1 << 13) | pid : 0);
L
Linus Torvalds 已提交
801 802
	return 0;
}
803
EXPORT_SYMBOL(dib3000mc_pid_control);
L
Linus Torvalds 已提交
804

805
int dib3000mc_pid_parse(struct dvb_frontend *fe, int onoff)
L
Linus Torvalds 已提交
806
{
807 808 809 810
	struct dib3000mc_state *state = fe->demodulator_priv;
	u16 tmp = dib3000mc_read_word(state, 206) & ~(1 << 4);
	tmp |= (onoff << 4);
	return dib3000mc_write_word(state, 206, tmp);
L
Linus Torvalds 已提交
811
}
812
EXPORT_SYMBOL(dib3000mc_pid_parse);
L
Linus Torvalds 已提交
813

814
void dib3000mc_set_config(struct dvb_frontend *fe, struct dib3000mc_config *cfg)
815
{
816 817
	struct dib3000mc_state *state = fe->demodulator_priv;
	state->cfg = cfg;
818
}
819
EXPORT_SYMBOL(dib3000mc_set_config);
L
Linus Torvalds 已提交
820

821
int dib3000mc_i2c_enumeration(struct i2c_adapter *i2c, int no_of_demods, u8 default_addr, struct dib3000mc_config cfg[])
L
Linus Torvalds 已提交
822
{
823
	struct dib3000mc_state *dmcst;
824 825
	int k;
	u8 new_addr;
L
Linus Torvalds 已提交
826

827
	static u8 DIB3000MC_I2C_ADDRESS[] = {20,22,24,26};
L
Linus Torvalds 已提交
828

829 830
	dmcst = kzalloc(sizeof(struct dib3000mc_state), GFP_KERNEL);
	if (dmcst == NULL)
831
		return -ENOMEM;
832 833 834

	dmcst->i2c_adap = i2c;

835
	for (k = no_of_demods-1; k >= 0; k--) {
836
		dmcst->cfg = &cfg[k];
L
Linus Torvalds 已提交
837

838 839
		/* designated i2c address */
		new_addr          = DIB3000MC_I2C_ADDRESS[k];
840 841 842 843
		dmcst->i2c_addr = new_addr;
		if (dib3000mc_identify(dmcst) != 0) {
			dmcst->i2c_addr = default_addr;
			if (dib3000mc_identify(dmcst) != 0) {
844
				dprintk("-E-  DiB3000P/MC #%d: not identified\n", k);
845
				kfree(dmcst);
846 847 848
				return -ENODEV;
			}
		}
L
Linus Torvalds 已提交
849

850
		dib3000mc_set_output_mode(dmcst, OUTMODE_MPEG2_PAR_CONT_CLK);
L
Linus Torvalds 已提交
851

852
		// set new i2c address and force divstr (Bit 1) to value 0 (Bit 0)
853 854
		dib3000mc_write_word(dmcst, 1024, (new_addr << 3) | 0x1);
		dmcst->i2c_addr = new_addr;
855
	}
L
Linus Torvalds 已提交
856

857
	for (k = 0; k < no_of_demods; k++) {
858 859
		dmcst->cfg = &cfg[k];
		dmcst->i2c_addr = DIB3000MC_I2C_ADDRESS[k];
L
Linus Torvalds 已提交
860

861
		dib3000mc_write_word(dmcst, 1024, dmcst->i2c_addr << 3);
L
Linus Torvalds 已提交
862

863
		/* turn off data output */
864
		dib3000mc_set_output_mode(dmcst, OUTMODE_HIGH_Z);
865
	}
866 867

	kfree(dmcst);
868
	return 0;
869 870 871 872 873 874 875 876 877 878 879 880 881 882 883
}
EXPORT_SYMBOL(dib3000mc_i2c_enumeration);

static struct dvb_frontend_ops dib3000mc_ops;

struct dvb_frontend * dib3000mc_attach(struct i2c_adapter *i2c_adap, u8 i2c_addr, struct dib3000mc_config *cfg)
{
	struct dvb_frontend *demod;
	struct dib3000mc_state *st;
	st = kzalloc(sizeof(struct dib3000mc_state), GFP_KERNEL);
	if (st == NULL)
		return NULL;

	st->cfg = cfg;
	st->i2c_adap = i2c_adap;
884
	st->i2c_addr = i2c_addr;
885 886 887 888 889 890 891 892 893 894

	demod                   = &st->demod;
	demod->demodulator_priv = st;
	memcpy(&st->demod.ops, &dib3000mc_ops, sizeof(struct dvb_frontend_ops));

	if (dib3000mc_identify(st) != 0)
		goto error;

	dibx000_init_i2c_master(&st->i2c_master, DIB3000MC, st->i2c_adap, st->i2c_addr);

895 896
	dib3000mc_write_word(st, 1037, 0x3130);

897
	return demod;
L
Linus Torvalds 已提交
898 899

error:
900 901
	kfree(st);
	return NULL;
L
Linus Torvalds 已提交
902
}
903
EXPORT_SYMBOL(dib3000mc_attach);
L
Linus Torvalds 已提交
904 905

static struct dvb_frontend_ops dib3000mc_ops = {
906
	.delsys = { SYS_DVBT },
L
Linus Torvalds 已提交
907
	.info = {
908 909 910 911
		.name = "DiBcom 3000MC/P",
		.frequency_min      = 44250000,
		.frequency_max      = 867250000,
		.frequency_stepsize = 62500,
L
Linus Torvalds 已提交
912
		.caps = FE_CAN_INVERSION_AUTO |
913 914 915 916 917 918 919
			FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4 |
			FE_CAN_FEC_5_6 | FE_CAN_FEC_7_8 | FE_CAN_FEC_AUTO |
			FE_CAN_QPSK | FE_CAN_QAM_16 | FE_CAN_QAM_64 | FE_CAN_QAM_AUTO |
			FE_CAN_TRANSMISSION_MODE_AUTO |
			FE_CAN_GUARD_INTERVAL_AUTO |
			FE_CAN_RECOVER |
			FE_CAN_HIERARCHY_AUTO,
L
Linus Torvalds 已提交
920 921
	},

922
	.release              = dib3000mc_release,
L
Linus Torvalds 已提交
923

924 925
	.init                 = dib3000mc_init,
	.sleep                = dib3000mc_sleep,
L
Linus Torvalds 已提交
926

927
	.set_frontend         = dib3000mc_set_frontend,
928
	.get_tune_settings    = dib3000mc_fe_get_tune_settings,
929
	.get_frontend         = dib3000mc_get_frontend,
L
Linus Torvalds 已提交
930

931 932
	.read_status          = dib3000mc_read_status,
	.read_ber             = dib3000mc_read_ber,
L
Linus Torvalds 已提交
933
	.read_signal_strength = dib3000mc_read_signal_strength,
934 935
	.read_snr             = dib3000mc_read_snr,
	.read_ucblocks        = dib3000mc_read_unc_blocks,
L
Linus Torvalds 已提交
936 937
};

938 939
MODULE_AUTHOR("Patrick Boettcher <pboettcher@dibcom.fr>");
MODULE_DESCRIPTION("Driver for the DiBcom 3000MC/P COFDM demodulator");
L
Linus Torvalds 已提交
940
MODULE_LICENSE("GPL");