cx24123.c 27.1 KB
Newer Older
1 2 3 4 5
/*
    Conexant cx24123/cx24109 - DVB QPSK Satellite demod/tuner driver

    Copyright (C) 2005 Steven Toth <stoth@hauppauge.com>

6 7
    Support for KWorld DVB-S 100 by Vadim Catana <skystar@moldova.cc>

8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31
    This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation; either version 2 of the License, or
    (at your option) any later version.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with this program; if not, write to the Free Software
    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/

#include <linux/slab.h>
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/moduleparam.h>
#include <linux/init.h>

#include "dvb_frontend.h"
#include "cx24123.h"

32 33
#define XTAL 10111000

34
static int force_band;
35 36 37 38 39 40
static int debug;
#define dprintk(args...) \
	do { \
		if (debug) printk (KERN_DEBUG "cx24123: " args); \
	} while (0)

41 42
struct cx24123_state
{
43 44 45 46 47 48 49 50 51 52
	struct i2c_adapter* i2c;
	const struct cx24123_config* config;

	struct dvb_frontend frontend;

	/* Some PLL specifics for tuning */
	u32 VCAarg;
	u32 VGAarg;
	u32 bandselectarg;
	u32 pllarg;
53
	u32 FILTune;
54 55 56 57 58 59

	/* The Demod/Tuner can't easily provide these, we cache them */
	u32 currentfreq;
	u32 currentsymbolrate;
};

60 61 62 63 64 65 66
/* Various tuner defaults need to be established for a given symbol rate Sps */
static struct
{
	u32 symbolrate_low;
	u32 symbolrate_high;
	u32 VCAprogdata;
	u32 VGAprogdata;
67
	u32 FILTune;
68 69 70 71 72
} cx24123_AGC_vals[] =
{
	{
		.symbolrate_low		= 1000000,
		.symbolrate_high	= 4999999,
73 74
		/* the specs recommend other values for VGA offsets,
		   but tests show they are wrong */
75 76 77
		.VGAprogdata		= (1 << 19) | (0x180 << 9) | 0x1e0,
		.VCAprogdata		= (2 << 19) | (0x07 << 9) | 0x07,
		.FILTune		= 0x27f /* 0.41 V */
78 79 80 81
	},
	{
		.symbolrate_low		=  5000000,
		.symbolrate_high	= 14999999,
82 83
		.VGAprogdata		= (1 << 19) | (0x180 << 9) | 0x1e0,
		.VCAprogdata		= (2 << 19) | (0x07 << 9) | 0x1f,
84
		.FILTune		= 0x317 /* 0.90 V */
85 86 87 88
	},
	{
		.symbolrate_low		= 15000000,
		.symbolrate_high	= 45000000,
89 90 91
		.VGAprogdata		= (1 << 19) | (0x100 << 9) | 0x180,
		.VCAprogdata		= (2 << 19) | (0x07 << 9) | 0x3f,
		.FILTune		= 0x145 /* 2.70 V */
92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107
	},
};

/*
 * Various tuner defaults need to be established for a given frequency kHz.
 * fixme: The bounds on the bands do not match the doc in real life.
 * fixme: Some of them have been moved, other might need adjustment.
 */
static struct
{
	u32 freq_low;
	u32 freq_high;
	u32 VCOdivider;
	u32 progdata;
} cx24123_bandselect_vals[] =
{
108
	/* band 1 */
109 110 111 112
	{
		.freq_low	= 950000,
		.freq_high	= 1074999,
		.VCOdivider	= 4,
113
		.progdata	= (0 << 19) | (0 << 9) | 0x40,
114
	},
115 116

	/* band 2 */
117 118
	{
		.freq_low	= 1075000,
119 120 121
		.freq_high	= 1177999,
		.VCOdivider	= 4,
		.progdata	= (0 << 19) | (0 << 9) | 0x80,
122
	},
123 124

	/* band 3 */
125
	{
126 127
		.freq_low	= 1178000,
		.freq_high	= 1295999,
128
		.VCOdivider	= 2,
129
		.progdata	= (0 << 19) | (1 << 9) | 0x01,
130
	},
131 132

	/* band 4 */
133
	{
134 135
		.freq_low	= 1296000,
		.freq_high	= 1431999,
136
		.VCOdivider	= 2,
137
		.progdata	= (0 << 19) | (1 << 9) | 0x02,
138
	},
139 140

	/* band 5 */
141
	{
142 143
		.freq_low	= 1432000,
		.freq_high	= 1575999,
144
		.VCOdivider	= 2,
145
		.progdata	= (0 << 19) | (1 << 9) | 0x04,
146
	},
147 148

	/* band 6 */
149
	{
150
		.freq_low	= 1576000,
151 152
		.freq_high	= 1717999,
		.VCOdivider	= 2,
153
		.progdata	= (0 << 19) | (1 << 9) | 0x08,
154
	},
155 156

	/* band 7 */
157 158 159 160
	{
		.freq_low	= 1718000,
		.freq_high	= 1855999,
		.VCOdivider	= 2,
161
		.progdata	= (0 << 19) | (1 << 9) | 0x10,
162
	},
163 164

	/* band 8 */
165 166 167 168
	{
		.freq_low	= 1856000,
		.freq_high	= 2035999,
		.VCOdivider	= 2,
169
		.progdata	= (0 << 19) | (1 << 9) | 0x20,
170
	},
171 172

	/* band 9 */
173 174
	{
		.freq_low	= 2036000,
175
		.freq_high	= 2150000,
176
		.VCOdivider	= 2,
177
		.progdata	= (0 << 19) | (1 << 9) | 0x40,
178 179 180
	},
};

181 182 183 184 185 186 187
static struct {
	u8 reg;
	u8 data;
} cx24123_regdata[] =
{
	{0x00, 0x03}, /* Reset system */
	{0x00, 0x00}, /* Clear reset */
188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207
	{0x03, 0x07}, /* QPSK, DVB, Auto Acquisition (default) */
	{0x04, 0x10}, /* MPEG */
	{0x05, 0x04}, /* MPEG */
	{0x06, 0x31}, /* MPEG (default) */
	{0x0b, 0x00}, /* Freq search start point (default) */
	{0x0c, 0x00}, /* Demodulator sample gain (default) */
	{0x0d, 0x02}, /* Frequency search range = Fsymbol / 4 (default) */
	{0x0e, 0x03}, /* Default non-inverted, FEC 3/4 (default) */
	{0x0f, 0xfe}, /* FEC search mask (all supported codes) */
	{0x10, 0x01}, /* Default search inversion, no repeat (default) */
	{0x16, 0x00}, /* Enable reading of frequency */
	{0x17, 0x01}, /* Enable EsNO Ready Counter */
	{0x1c, 0x80}, /* Enable error counter */
	{0x20, 0x00}, /* Tuner burst clock rate = 500KHz */
	{0x21, 0x15}, /* Tuner burst mode, word length = 0x15 */
	{0x28, 0x00}, /* Enable FILTERV with positive pol., DiSEqC 2.x off */
	{0x29, 0x00}, /* DiSEqC LNB_DC off */
	{0x2a, 0xb0}, /* DiSEqC Parameters (default) */
	{0x2b, 0x73}, /* DiSEqC Tone Frequency (default) */
	{0x2c, 0x00}, /* DiSEqC Message (0x2c - 0x31) */
208 209 210 211 212
	{0x2d, 0x00},
	{0x2e, 0x00},
	{0x2f, 0x00},
	{0x30, 0x00},
	{0x31, 0x00},
213 214
	{0x32, 0x8c}, /* DiSEqC Parameters (default) */
	{0x33, 0x00}, /* Interrupts off (0x33 - 0x34) */
215
	{0x34, 0x00},
216 217 218 219 220 221 222
	{0x35, 0x03}, /* DiSEqC Tone Amplitude (default) */
	{0x36, 0x02}, /* DiSEqC Parameters (default) */
	{0x37, 0x3a}, /* DiSEqC Parameters (default) */
	{0x3a, 0x00}, /* Enable AGC accumulator (for signal strength) */
	{0x44, 0x00}, /* Constellation (default) */
	{0x45, 0x00}, /* Symbol count (default) */
	{0x46, 0x0d}, /* Symbol rate estimator on (default) */
Y
Yeasah Pell 已提交
223
	{0x56, 0xc1}, /* Error Counter = Viterbi BER */
224 225
	{0x57, 0xff}, /* Error Counter Window (default) */
	{0x67, 0x83}, /* Non-DCII symbol clock */
226 227 228 229 230 231 232 233
};

static int cx24123_writereg(struct cx24123_state* state, int reg, int data)
{
	u8 buf[] = { reg, data };
	struct i2c_msg msg = { .addr = state->config->demod_address, .flags = 0, .buf = buf, .len = 2 };
	int err;

234 235 236 237
	if (debug>1)
		printk("cx24123: %s:  write reg 0x%02x, value 0x%02x\n",
						__FUNCTION__,reg, data);

238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263
	if ((err = i2c_transfer(state->i2c, &msg, 1)) != 1) {
		printk("%s: writereg error(err == %i, reg == 0x%02x,"
			 " data == 0x%02x)\n", __FUNCTION__, err, reg, data);
		return -EREMOTEIO;
	}

	return 0;
}

static int cx24123_readreg(struct cx24123_state* state, u8 reg)
{
	int ret;
	u8 b0[] = { reg };
	u8 b1[] = { 0 };
	struct i2c_msg msg[] = {
		{ .addr = state->config->demod_address, .flags = 0, .buf = b0, .len = 1 },
		{ .addr = state->config->demod_address, .flags = I2C_M_RD, .buf = b1, .len = 1 }
	};

	ret = i2c_transfer(state->i2c, msg, 2);

	if (ret != 2) {
		printk("%s: reg=0x%x (error=%d)\n", __FUNCTION__, reg, ret);
		return ret;
	}

264 265 266
	if (debug>1)
		printk("cx24123: read reg 0x%02x, value 0x%02x\n",reg, ret);

267 268 269 270 271
	return b1[0];
}

static int cx24123_set_inversion(struct cx24123_state* state, fe_spectral_inversion_t inversion)
{
272 273 274
	u8 nom_reg = cx24123_readreg(state, 0x0e);
	u8 auto_reg = cx24123_readreg(state, 0x10);

275 276
	switch (inversion) {
	case INVERSION_OFF:
277
		dprintk("%s:  inversion off\n",__FUNCTION__);
278 279
		cx24123_writereg(state, 0x0e, nom_reg & ~0x80);
		cx24123_writereg(state, 0x10, auto_reg | 0x80);
280 281
		break;
	case INVERSION_ON:
282
		dprintk("%s:  inversion on\n",__FUNCTION__);
283 284
		cx24123_writereg(state, 0x0e, nom_reg | 0x80);
		cx24123_writereg(state, 0x10, auto_reg | 0x80);
285 286
		break;
	case INVERSION_AUTO:
287
		dprintk("%s:  inversion auto\n",__FUNCTION__);
288
		cx24123_writereg(state, 0x10, auto_reg & ~0x80);
289 290 291 292 293 294 295 296 297 298 299 300 301 302
		break;
	default:
		return -EINVAL;
	}

	return 0;
}

static int cx24123_get_inversion(struct cx24123_state* state, fe_spectral_inversion_t *inversion)
{
	u8 val;

	val = cx24123_readreg(state, 0x1b) >> 7;

303 304
	if (val == 0) {
		dprintk("%s:  read inversion off\n",__FUNCTION__);
305
		*inversion = INVERSION_OFF;
306 307
	} else {
		dprintk("%s:  read inversion on\n",__FUNCTION__);
308
		*inversion = INVERSION_ON;
309
	}
310 311 312 313 314 315

	return 0;
}

static int cx24123_set_fec(struct cx24123_state* state, fe_code_rate_t fec)
{
316 317
	u8 nom_reg = cx24123_readreg(state, 0x0e) & ~0x07;

318
	if ( (fec < FEC_NONE) || (fec > FEC_AUTO) )
319
		fec = FEC_AUTO;
320

321 322 323 324 325 326
	/* Set the soft decision threshold */
	if(fec == FEC_1_2)
		cx24123_writereg(state, 0x43, cx24123_readreg(state, 0x43) | 0x01);
	else
		cx24123_writereg(state, 0x43, cx24123_readreg(state, 0x43) & ~0x01);

327 328
	switch (fec) {
	case FEC_1_2:
329
		dprintk("%s:  set FEC to 1/2\n",__FUNCTION__);
330 331 332
		cx24123_writereg(state, 0x0e, nom_reg | 0x01);
		cx24123_writereg(state, 0x0f, 0x02);
		break;
333
	case FEC_2_3:
334
		dprintk("%s:  set FEC to 2/3\n",__FUNCTION__);
335 336 337
		cx24123_writereg(state, 0x0e, nom_reg | 0x02);
		cx24123_writereg(state, 0x0f, 0x04);
		break;
338
	case FEC_3_4:
339
		dprintk("%s:  set FEC to 3/4\n",__FUNCTION__);
340 341 342 343
		cx24123_writereg(state, 0x0e, nom_reg | 0x03);
		cx24123_writereg(state, 0x0f, 0x08);
		break;
	case FEC_4_5:
344
		dprintk("%s:  set FEC to 4/5\n",__FUNCTION__);
345 346 347 348
		cx24123_writereg(state, 0x0e, nom_reg | 0x04);
		cx24123_writereg(state, 0x0f, 0x10);
		break;
	case FEC_5_6:
349
		dprintk("%s:  set FEC to 5/6\n",__FUNCTION__);
350 351 352 353 354 355 356 357 358 359 360 361 362
		cx24123_writereg(state, 0x0e, nom_reg | 0x05);
		cx24123_writereg(state, 0x0f, 0x20);
		break;
	case FEC_6_7:
		dprintk("%s:  set FEC to 6/7\n",__FUNCTION__);
		cx24123_writereg(state, 0x0e, nom_reg | 0x06);
		cx24123_writereg(state, 0x0f, 0x40);
		break;
	case FEC_7_8:
		dprintk("%s:  set FEC to 7/8\n",__FUNCTION__);
		cx24123_writereg(state, 0x0e, nom_reg | 0x07);
		cx24123_writereg(state, 0x0f, 0x80);
		break;
363
	case FEC_AUTO:
364
		dprintk("%s:  set FEC to auto\n",__FUNCTION__);
365 366
		cx24123_writereg(state, 0x0f, 0xfe);
		break;
367 368 369
	default:
		return -EOPNOTSUPP;
	}
370 371

	return 0;
372 373 374 375
}

static int cx24123_get_fec(struct cx24123_state* state, fe_code_rate_t *fec)
{
376
	int ret;
377

378 379 380
	ret = cx24123_readreg (state, 0x1b);
	if (ret < 0)
		return ret;
381 382 383
	ret = ret & 0x07;

	switch (ret) {
384
	case 1:
385 386
		*fec = FEC_1_2;
		break;
387
	case 2:
388 389
		*fec = FEC_2_3;
		break;
390
	case 3:
391 392
		*fec = FEC_3_4;
		break;
393
	case 4:
394 395
		*fec = FEC_4_5;
		break;
396
	case 5:
397 398
		*fec = FEC_5_6;
		break;
399 400 401
	case 6:
		*fec = FEC_6_7;
		break;
402
	case 7:
403 404
		*fec = FEC_7_8;
		break;
405
	default:
406 407
		/* this can happen when there's no lock */
		*fec = FEC_NONE;
408 409
	}

410
	return 0;
411 412
}

413 414 415 416 417 418 419 420 421 422 423 424 425 426 427
/* Approximation of closest integer of log2(a/b). It actually gives the
   lowest integer i such that 2^i >= round(a/b) */
static u32 cx24123_int_log2(u32 a, u32 b)
{
	u32 exp, nearest = 0;
	u32 div = a / b;
	if(a % b >= b / 2) ++div;
	if(div < (1 << 31))
	{
		for(exp = 1; div > exp; nearest++)
			exp += exp;
	}
	return nearest;
}

428 429
static int cx24123_set_symbolrate(struct cx24123_state* state, u32 srate)
{
430
	u32 tmp, sample_rate, ratio, sample_gain;
431 432 433
	u8 pll_mult;

	/*  check if symbol rate is within limits */
434 435
	if ((srate > state->frontend.ops.info.symbol_rate_max) ||
	    (srate < state->frontend.ops.info.symbol_rate_min))
436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458
		return -EOPNOTSUPP;;

	/* choose the sampling rate high enough for the required operation,
	   while optimizing the power consumed by the demodulator */
	if (srate < (XTAL*2)/2)
		pll_mult = 2;
	else if (srate < (XTAL*3)/2)
		pll_mult = 3;
	else if (srate < (XTAL*4)/2)
		pll_mult = 4;
	else if (srate < (XTAL*5)/2)
		pll_mult = 5;
	else if (srate < (XTAL*6)/2)
		pll_mult = 6;
	else if (srate < (XTAL*7)/2)
		pll_mult = 7;
	else if (srate < (XTAL*8)/2)
		pll_mult = 8;
	else
		pll_mult = 9;


	sample_rate = pll_mult * XTAL;
459

460 461
	/*
	    SYSSymbolRate[21:0] = (srate << 23) / sample_rate
462

463 464 465 466 467
	    We have to use 32 bit unsigned arithmetic without precision loss.
	    The maximum srate is 45000000 or 0x02AEA540. This number has
	    only 6 clear bits on top, hence we can shift it left only 6 bits
	    at a time. Borrowed from cx24110.c
	*/
468

469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487
	tmp = srate << 6;
	ratio = tmp / sample_rate;

	tmp = (tmp % sample_rate) << 6;
	ratio = (ratio << 6) + (tmp / sample_rate);

	tmp = (tmp % sample_rate) << 6;
	ratio = (ratio << 6) + (tmp / sample_rate);

	tmp = (tmp % sample_rate) << 5;
	ratio = (ratio << 5) + (tmp / sample_rate);


	cx24123_writereg(state, 0x01, pll_mult * 6);

	cx24123_writereg(state, 0x08, (ratio >> 16) & 0x3f );
	cx24123_writereg(state, 0x09, (ratio >>  8) & 0xff );
	cx24123_writereg(state, 0x0a, (ratio      ) & 0xff );

488 489 490 491 492 493
	/* also set the demodulator sample gain */
	sample_gain = cx24123_int_log2(sample_rate, srate);
	tmp = cx24123_readreg(state, 0x0c) & ~0xe0;
	cx24123_writereg(state, 0x0c, tmp | sample_gain << 5);

	dprintk("%s: srate=%d, ratio=0x%08x, sample_rate=%i sample_gain=%d\n", __FUNCTION__, srate, ratio, sample_rate, sample_gain);
494 495 496 497 498 499 500 501 502 503 504

	return 0;
}

/*
 * Based on the required frequency and symbolrate, the tuner AGC has to be configured
 * and the correct band selected. Calculate those values
 */
static int cx24123_pll_calculate(struct dvb_frontend* fe, struct dvb_frontend_parameters *p)
{
	struct cx24123_state *state = fe->demodulator_priv;
505 506
	u32 ndiv = 0, adiv = 0, vco_div = 0;
	int i = 0;
507
	int pump = 2;
508 509
	int band = 0;
	int num_bands = sizeof(cx24123_bandselect_vals) / sizeof(cx24123_bandselect_vals[0]);
510 511 512 513 514 515 516

	/* Defaults for low freq, low rate */
	state->VCAarg = cx24123_AGC_vals[0].VCAprogdata;
	state->VGAarg = cx24123_AGC_vals[0].VGAprogdata;
	state->bandselectarg = cx24123_bandselect_vals[0].progdata;
	vco_div = cx24123_bandselect_vals[0].VCOdivider;

517
	/* For the given symbol rate, determine the VCA, VGA and FILTUNE programming bits */
518
	for (i = 0; i < sizeof(cx24123_AGC_vals) / sizeof(cx24123_AGC_vals[0]); i++)
519 520
	{
		if ((cx24123_AGC_vals[i].symbolrate_low <= p->u.qpsk.symbol_rate) &&
521
		    (cx24123_AGC_vals[i].symbolrate_high >= p->u.qpsk.symbol_rate) ) {
522 523
			state->VCAarg = cx24123_AGC_vals[i].VCAprogdata;
			state->VGAarg = cx24123_AGC_vals[i].VGAprogdata;
524
			state->FILTune = cx24123_AGC_vals[i].FILTune;
525 526 527
		}
	}

528 529
	/* determine the band to use */
	if(force_band < 1 || force_band > num_bands)
530
	{
531 532 533 534 535
		for (i = 0; i < num_bands; i++)
		{
			if ((cx24123_bandselect_vals[i].freq_low <= p->frequency) &&
			    (cx24123_bandselect_vals[i].freq_high >= p->frequency) )
				band = i;
536 537
		}
	}
538 539 540 541 542 543 544 545 546 547 548
	else
		band = force_band - 1;

	state->bandselectarg = cx24123_bandselect_vals[band].progdata;
	vco_div = cx24123_bandselect_vals[band].VCOdivider;

	/* determine the charge pump current */
	if ( p->frequency < (cx24123_bandselect_vals[band].freq_low + cx24123_bandselect_vals[band].freq_high)/2 )
		pump = 0x01;
	else
		pump = 0x02;
549 550

	/* Determine the N/A dividers for the requested lband freq (in kHz). */
551 552 553
	/* Note: the reference divider R=10, frequency is in KHz, XTAL is in Hz */
	ndiv = ( ((p->frequency * vco_div * 10) / (2 * XTAL / 1000)) / 32) & 0x1ff;
	adiv = ( ((p->frequency * vco_div * 10) / (2 * XTAL / 1000)) % 32) & 0x1f;
554 555

	if (adiv == 0)
556
		ndiv++;
557

558 559
	/* control bits 11, refdiv 11, charge pump polarity 1, charge pump current, ndiv, adiv */
	state->pllarg = (3 << 19) | (3 << 17) | (1 << 16) | (pump << 14) | (ndiv << 5) | adiv;
560 561 562 563 564 565 566 567 568 569 570

	return 0;
}

/*
 * Tuner data is 21 bits long, must be left-aligned in data.
 * Tuner cx24109 is written through a dedicated 3wire interface on the demod chip.
 */
static int cx24123_pll_writereg(struct dvb_frontend* fe, struct dvb_frontend_parameters *p, u32 data)
{
	struct cx24123_state *state = fe->demodulator_priv;
571
	unsigned long timeout;
572

573 574
	dprintk("%s:  pll writereg called, data=0x%08x\n",__FUNCTION__,data);

575 576 577 578 579 580 581
	/* align the 21 bytes into to bit23 boundary */
	data = data << 3;

	/* Reset the demod pll word length to 0x15 bits */
	cx24123_writereg(state, 0x21, 0x15);

	/* write the msb 8 bits, wait for the send to be completed */
582
	timeout = jiffies + msecs_to_jiffies(40);
583
	cx24123_writereg(state, 0x22, (data >> 16) & 0xff);
584 585 586
	while ((cx24123_readreg(state, 0x20) & 0x40) == 0) {
		if (time_after(jiffies, timeout)) {
			printk("%s:  demodulator is not responding, possibly hung, aborting.\n", __FUNCTION__);
587 588
			return -EREMOTEIO;
		}
589
		msleep(10);
590 591 592
	}

	/* send another 8 bytes, wait for the send to be completed */
593
	timeout = jiffies + msecs_to_jiffies(40);
594
	cx24123_writereg(state, 0x22, (data>>8) & 0xff );
595 596 597
	while ((cx24123_readreg(state, 0x20) & 0x40) == 0) {
		if (time_after(jiffies, timeout)) {
			printk("%s:  demodulator is not responding, possibly hung, aborting.\n", __FUNCTION__);
598 599
			return -EREMOTEIO;
		}
600
		msleep(10);
601 602 603
	}

	/* send the lower 5 bits of this byte, padded with 3 LBB, wait for the send to be completed */
604
	timeout = jiffies + msecs_to_jiffies(40);
605
	cx24123_writereg(state, 0x22, (data) & 0xff );
606 607 608
	while ((cx24123_readreg(state, 0x20) & 0x80)) {
		if (time_after(jiffies, timeout)) {
			printk("%s:  demodulator is not responding, possibly hung, aborting.\n", __FUNCTION__);
609 610
			return -EREMOTEIO;
		}
611
		msleep(10);
612 613 614 615 616 617 618 619 620 621 622 623
	}

	/* Trigger the demod to configure the tuner */
	cx24123_writereg(state, 0x20, cx24123_readreg(state, 0x20) | 2);
	cx24123_writereg(state, 0x20, cx24123_readreg(state, 0x20) & 0xfd);

	return 0;
}

static int cx24123_pll_tune(struct dvb_frontend* fe, struct dvb_frontend_parameters *p)
{
	struct cx24123_state *state = fe->demodulator_priv;
624 625 626
	u8 val;

	dprintk("frequency=%i\n", p->frequency);
627

628
	if (cx24123_pll_calculate(fe, p) != 0) {
629 630 631 632 633 634 635 636 637 638 639 640
		printk("%s: cx24123_pll_calcutate failed\n",__FUNCTION__);
		return -EINVAL;
	}

	/* Write the new VCO/VGA */
	cx24123_pll_writereg(fe, p, state->VCAarg);
	cx24123_pll_writereg(fe, p, state->VGAarg);

	/* Write the new bandselect and pll args */
	cx24123_pll_writereg(fe, p, state->bandselectarg);
	cx24123_pll_writereg(fe, p, state->pllarg);

641 642 643 644 645
	/* set the FILTUNE voltage */
	val = cx24123_readreg(state, 0x28) & ~0x3;
	cx24123_writereg(state, 0x27, state->FILTune >> 2);
	cx24123_writereg(state, 0x28, val | (state->FILTune & 0x3));

646 647 648
	dprintk("%s:  pll tune VCA=%d, band=%d, pll=%d\n",__FUNCTION__,state->VCAarg,
			state->bandselectarg,state->pllarg);

649 650 651 652 653 654 655 656
	return 0;
}

static int cx24123_initfe(struct dvb_frontend* fe)
{
	struct cx24123_state *state = fe->demodulator_priv;
	int i;

657 658
	dprintk("%s:  init frontend\n",__FUNCTION__);

659
	/* Configure the demod to a good set of defaults */
660
	for (i = 0; i < sizeof(cx24123_regdata) / sizeof(cx24123_regdata[0]); i++)
661 662 663 664 665 666 667 668 669 670
		cx24123_writereg(state, cx24123_regdata[i].reg, cx24123_regdata[i].data);

	return 0;
}

static int cx24123_set_voltage(struct dvb_frontend* fe, fe_sec_voltage_t voltage)
{
	struct cx24123_state *state = fe->demodulator_priv;
	u8 val;

671
	val = cx24123_readreg(state, 0x29) & ~0x40;
672

673 674 675
	switch (voltage) {
	case SEC_VOLTAGE_13:
		dprintk("%s: setting voltage 13V\n", __FUNCTION__);
676
		return cx24123_writereg(state, 0x29, val & 0x7f);
677 678
	case SEC_VOLTAGE_18:
		dprintk("%s: setting voltage 18V\n", __FUNCTION__);
679
		return cx24123_writereg(state, 0x29, val | 0x80);
680 681 682
	default:
		return -EINVAL;
	};
683 684

	return 0;
685 686
}

687 688 689 690 691 692 693 694 695 696 697 698 699
/* wait for diseqc queue to become ready (or timeout) */
static void cx24123_wait_for_diseqc(struct cx24123_state *state)
{
	unsigned long timeout = jiffies + msecs_to_jiffies(200);
	while (!(cx24123_readreg(state, 0x29) & 0x40)) {
		if(time_after(jiffies, timeout)) {
			printk("%s: diseqc queue not ready, command may be lost.\n", __FUNCTION__);
			break;
		}
		msleep(10);
	}
}

700
static int cx24123_send_diseqc_msg(struct dvb_frontend* fe, struct dvb_diseqc_master_cmd *cmd)
701
{
702
	struct cx24123_state *state = fe->demodulator_priv;
703
	int i, val, tone;
704 705

	dprintk("%s:\n",__FUNCTION__);
706

707 708 709 710
	/* stop continuous tone if enabled */
	tone = cx24123_readreg(state, 0x29);
	if (tone & 0x10)
		cx24123_writereg(state, 0x29, tone & ~0x50);
711

712 713 714
	/* wait for diseqc queue ready */
	cx24123_wait_for_diseqc(state);

715
	/* select tone mode */
716
	cx24123_writereg(state, 0x2a, cx24123_readreg(state, 0x2a) & 0xfb);
717 718 719 720 721 722 723

	for (i = 0; i < cmd->msg_len; i++)
		cx24123_writereg(state, 0x2C + i, cmd->msg[i]);

	val = cx24123_readreg(state, 0x29);
	cx24123_writereg(state, 0x29, ((val & 0x90) | 0x40) | ((cmd->msg_len-3) & 3));

724 725
	/* wait for diseqc message to finish sending */
	cx24123_wait_for_diseqc(state);
726

727 728 729 730 731
	/* restart continuous tone if enabled */
	if (tone & 0x10) {
		cx24123_writereg(state, 0x29, tone & ~0x40);
	}

732 733 734 735 736 737
	return 0;
}

static int cx24123_diseqc_send_burst(struct dvb_frontend* fe, fe_sec_mini_cmd_t burst)
{
	struct cx24123_state *state = fe->demodulator_priv;
738
	int val, tone;
739 740 741

	dprintk("%s:\n", __FUNCTION__);

742 743 744 745
	/* stop continuous tone if enabled */
	tone = cx24123_readreg(state, 0x29);
	if (tone & 0x10)
		cx24123_writereg(state, 0x29, tone & ~0x50);
746

747
	/* wait for diseqc queue ready */
748 749
	cx24123_wait_for_diseqc(state);

750
	/* select tone mode */
751 752
	cx24123_writereg(state, 0x2a, cx24123_readreg(state, 0x2a) | 0x4);
	msleep(30);
753 754 755 756 757 758 759 760
	val = cx24123_readreg(state, 0x29);
	if (burst == SEC_MINI_A)
		cx24123_writereg(state, 0x29, ((val & 0x90) | 0x40 | 0x00));
	else if (burst == SEC_MINI_B)
		cx24123_writereg(state, 0x29, ((val & 0x90) | 0x40 | 0x08));
	else
		return -EINVAL;

761
	cx24123_wait_for_diseqc(state);
762
	cx24123_writereg(state, 0x2a, cx24123_readreg(state, 0x2a) & 0xfb);
763

764 765 766 767
	/* restart continuous tone if enabled */
	if (tone & 0x10) {
		cx24123_writereg(state, 0x29, tone & ~0x40);
	}
768
	return 0;
769 770 771 772 773 774 775 776 777 778 779
}

static int cx24123_read_status(struct dvb_frontend* fe, fe_status_t* status)
{
	struct cx24123_state *state = fe->demodulator_priv;

	int sync = cx24123_readreg(state, 0x14);
	int lock = cx24123_readreg(state, 0x20);

	*status = 0;
	if (lock & 0x01)
780 781 782
		*status |= FE_HAS_SIGNAL;
	if (sync & 0x02)
		*status |= FE_HAS_CARRIER;
783 784 785
	if (sync & 0x04)
		*status |= FE_HAS_VITERBI;
	if (sync & 0x08)
786
		*status |= FE_HAS_SYNC;
787
	if (sync & 0x80)
788
		*status |= FE_HAS_LOCK;
789 790 791 792 793 794 795 796 797 798 799 800

	return 0;
}

/*
 * Configured to return the measurement of errors in blocks, because no UCBLOCKS value
 * is available, so this value doubles up to satisfy both measurements
 */
static int cx24123_read_ber(struct dvb_frontend* fe, u32* ber)
{
	struct cx24123_state *state = fe->demodulator_priv;

Y
Yeasah Pell 已提交
801 802 803
	/* The true bit error rate is this value divided by
	   the window size (set as 256 * 255) */
	*ber = ((cx24123_readreg(state, 0x1c) & 0x3f) << 16) |
804
		(cx24123_readreg(state, 0x1d) << 8 |
Y
Yeasah Pell 已提交
805
		 cx24123_readreg(state, 0x1e));
806

Y
Yeasah Pell 已提交
807
	dprintk("%s:  BER = %d\n",__FUNCTION__,*ber);
808 809 810 811 812 813 814 815 816

	return 0;
}

static int cx24123_read_signal_strength(struct dvb_frontend* fe, u16* signal_strength)
{
	struct cx24123_state *state = fe->demodulator_priv;
	*signal_strength = cx24123_readreg(state, 0x3b) << 8; /* larger = better */

817 818
	dprintk("%s:  Signal strength = %d\n",__FUNCTION__,*signal_strength);

819 820 821 822 823 824 825
	return 0;
}

static int cx24123_read_snr(struct dvb_frontend* fe, u16* snr)
{
	struct cx24123_state *state = fe->demodulator_priv;

Y
Yeasah Pell 已提交
826 827 828 829
	/* Inverted raw Es/N0 count, totally bogus but better than the
	   BER threshold. */
	*snr = 65535 - (((u16)cx24123_readreg(state, 0x18) << 8) |
			 (u16)cx24123_readreg(state, 0x19));
830

Y
Yeasah Pell 已提交
831
	dprintk("%s:  read S/N index = %d\n",__FUNCTION__,*snr);
832

833 834 835 836 837 838 839
	return 0;
}

static int cx24123_set_frontend(struct dvb_frontend* fe, struct dvb_frontend_parameters *p)
{
	struct cx24123_state *state = fe->demodulator_priv;

840 841
	dprintk("%s:  set_frontend\n",__FUNCTION__);

842 843 844 845
	if (state->config->set_ts_params)
		state->config->set_ts_params(fe, 0);

	state->currentfreq=p->frequency;
846
	state->currentsymbolrate = p->u.qpsk.symbol_rate;
847 848 849 850 851 852 853

	cx24123_set_inversion(state, p->inversion);
	cx24123_set_fec(state, p->u.qpsk.fec_inner);
	cx24123_set_symbolrate(state, p->u.qpsk.symbol_rate);
	cx24123_pll_tune(fe, p);

	/* Enable automatic aquisition and reset cycle */
854
	cx24123_writereg(state, 0x03, (cx24123_readreg(state, 0x03) | 0x07));
855 856 857 858 859 860 861 862 863 864
	cx24123_writereg(state, 0x00, 0x10);
	cx24123_writereg(state, 0x00, 0);

	return 0;
}

static int cx24123_get_frontend(struct dvb_frontend* fe, struct dvb_frontend_parameters *p)
{
	struct cx24123_state *state = fe->demodulator_priv;

865 866
	dprintk("%s:  get_frontend\n",__FUNCTION__);

867 868 869 870 871 872 873 874 875 876 877 878 879 880 881 882 883 884 885
	if (cx24123_get_inversion(state, &p->inversion) != 0) {
		printk("%s: Failed to get inversion status\n",__FUNCTION__);
		return -EREMOTEIO;
	}
	if (cx24123_get_fec(state, &p->u.qpsk.fec_inner) != 0) {
		printk("%s: Failed to get fec status\n",__FUNCTION__);
		return -EREMOTEIO;
	}
	p->frequency = state->currentfreq;
	p->u.qpsk.symbol_rate = state->currentsymbolrate;

	return 0;
}

static int cx24123_set_tone(struct dvb_frontend* fe, fe_sec_tone_mode_t tone)
{
	struct cx24123_state *state = fe->demodulator_priv;
	u8 val;

886 887
	/* wait for diseqc queue ready */
	cx24123_wait_for_diseqc(state);
888

889
	val = cx24123_readreg(state, 0x29) & ~0x40;
890

891 892 893 894 895 896 897 898 899 900
	switch (tone) {
	case SEC_TONE_ON:
		dprintk("%s: setting tone on\n", __FUNCTION__);
		return cx24123_writereg(state, 0x29, val | 0x10);
	case SEC_TONE_OFF:
		dprintk("%s: setting tone off\n",__FUNCTION__);
		return cx24123_writereg(state, 0x29, val & 0xef);
	default:
		printk("%s: CASE reached default with tone=%d\n", __FUNCTION__, tone);
		return -EINVAL;
901
	}
902 903

	return 0;
904 905
}

Y
Yeasah Pell 已提交
906 907 908 909 910 911 912 913 914 915 916 917 918 919 920 921 922 923 924 925 926 927 928
static int cx24123_tune(struct dvb_frontend* fe,
			struct dvb_frontend_parameters* params,
			unsigned int mode_flags,
			int *delay,
			fe_status_t *status)
{
	int retval = 0;

	if (params != NULL)
		retval = cx24123_set_frontend(fe, params);

	if (!(mode_flags & FE_TUNE_MODE_ONESHOT))
		cx24123_read_status(fe, status);
	*delay = HZ/10;

	return retval;
}

static int cx24123_get_algo(struct dvb_frontend *fe)
{
	return 1; //FE_ALGO_HW
}

929 930 931 932 933 934 935 936 937
static void cx24123_release(struct dvb_frontend* fe)
{
	struct cx24123_state* state = fe->demodulator_priv;
	dprintk("%s\n",__FUNCTION__);
	kfree(state);
}

static struct dvb_frontend_ops cx24123_ops;

938 939
struct dvb_frontend* cx24123_attach(const struct cx24123_config* config,
				    struct i2c_adapter* i2c)
940 941 942 943 944 945 946 947 948 949 950 951 952 953 954 955 956 957 958 959 960 961 962 963 964 965 966 967 968 969 970
{
	struct cx24123_state* state = NULL;
	int ret;

	dprintk("%s\n",__FUNCTION__);

	/* allocate memory for the internal state */
	state = kmalloc(sizeof(struct cx24123_state), GFP_KERNEL);
	if (state == NULL) {
		printk("Unable to kmalloc\n");
		goto error;
	}

	/* setup the state */
	state->config = config;
	state->i2c = i2c;
	state->VCAarg = 0;
	state->VGAarg = 0;
	state->bandselectarg = 0;
	state->pllarg = 0;
	state->currentfreq = 0;
	state->currentsymbolrate = 0;

	/* check if the demod is there */
	ret = cx24123_readreg(state, 0x00);
	if ((ret != 0xd1) && (ret != 0xe1)) {
		printk("Version != d1 or e1\n");
		goto error;
	}

	/* create dvb_frontend */
971
	memcpy(&state->frontend.ops, &cx24123_ops, sizeof(struct dvb_frontend_ops));
972 973 974 975 976 977 978 979 980 981 982 983 984 985 986 987 988
	state->frontend.demodulator_priv = state;
	return &state->frontend;

error:
	kfree(state);

	return NULL;
}

static struct dvb_frontend_ops cx24123_ops = {

	.info = {
		.name = "Conexant CX24123/CX24109",
		.type = FE_QPSK,
		.frequency_min = 950000,
		.frequency_max = 2150000,
		.frequency_stepsize = 1011, /* kHz for QPSK frontends */
989
		.frequency_tolerance = 5000,
990 991 992 993
		.symbol_rate_min = 1000000,
		.symbol_rate_max = 45000000,
		.caps = FE_CAN_INVERSION_AUTO |
			FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4 |
994 995
			FE_CAN_FEC_4_5 | FE_CAN_FEC_5_6 | FE_CAN_FEC_6_7 |
			FE_CAN_FEC_7_8 | FE_CAN_FEC_AUTO |
996 997 998 999 1000 1001 1002 1003 1004 1005 1006 1007 1008
			FE_CAN_QPSK | FE_CAN_RECOVER
	},

	.release = cx24123_release,

	.init = cx24123_initfe,
	.set_frontend = cx24123_set_frontend,
	.get_frontend = cx24123_get_frontend,
	.read_status = cx24123_read_status,
	.read_ber = cx24123_read_ber,
	.read_signal_strength = cx24123_read_signal_strength,
	.read_snr = cx24123_read_snr,
	.diseqc_send_master_cmd = cx24123_send_diseqc_msg,
1009
	.diseqc_send_burst = cx24123_diseqc_send_burst,
1010 1011
	.set_tone = cx24123_set_tone,
	.set_voltage = cx24123_set_voltage,
Y
Yeasah Pell 已提交
1012 1013
	.tune = cx24123_tune,
	.get_frontend_algo = cx24123_get_algo,
1014 1015 1016
};

module_param(debug, int, 0644);
1017
MODULE_PARM_DESC(debug, "Activates frontend debugging (default:0)");
1018

1019 1020 1021
module_param(force_band, int, 0644);
MODULE_PARM_DESC(force_band, "Force a specific band select (1-9, default:off).");

1022 1023 1024 1025 1026
MODULE_DESCRIPTION("DVB Frontend module for Conexant cx24123/cx24109 hardware");
MODULE_AUTHOR("Steven Toth");
MODULE_LICENSE("GPL");

EXPORT_SYMBOL(cx24123_attach);