cx24116.c 39.8 KB
Newer Older
1 2 3 4
/*
    Conexant cx24116/cx24118 - DVBS/S2 Satellite demod/tuner driver

    Copyright (C) 2006-2008 Steven Toth <stoth@hauppauge.com>
5 6 7 8 9 10 11 12 13 14 15
    Copyright (C) 2006-2007 Georg Acher
    Copyright (C) 2007-2008 Darron Broad
	March 2007
	    Fixed some bugs.
	    Added diseqc support.
	    Added corrected signal strength support.
	August 2007
	    Sync with legacy version.
	    Some clean ups.
    Copyright (C) 2008 Igor Liplianin
	September, 9th 2008
16 17
	    Fixed locking on high symbol rates (>30000).
	    Implement MPEG initialization parameter.
18 19 20
	January, 17th 2009
	    Fill set_voltage with actually control voltage code.
	    Correct set tone to not affect voltage.
21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46

    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 <linux/firmware.h>

#include "dvb_frontend.h"
#include "cx24116.h"

47 48 49 50
static int debug;
module_param(debug, int, 0644);
MODULE_PARM_DESC(debug, "Activates frontend debugging (default:0)");

51 52
#define dprintk(args...) \
	do { \
53
		if (debug) \
54
			printk(KERN_INFO "cx24116: " args); \
55 56
	} while (0)

57 58 59
#define CX24116_DEFAULT_FIRMWARE "dvb-fe-cx24116.fw"
#define CX24116_SEARCH_RANGE_KHZ 5000

60 61 62 63 64 65 66
/* known registers */
#define CX24116_REG_COMMAND (0x00)      /* command args 0x00..0x1e */
#define CX24116_REG_EXECUTE (0x1f)      /* execute command */
#define CX24116_REG_MAILBOX (0x96)      /* FW or multipurpose mailbox? */
#define CX24116_REG_RESET   (0x20)      /* reset status > 0     */
#define CX24116_REG_SIGNAL  (0x9e)      /* signal low           */
#define CX24116_REG_SSTATUS (0x9d)      /* signal high / status */
67
#define CX24116_REG_QUALITY8 (0xa3)
68
#define CX24116_REG_QSTATUS (0xbc)
69
#define CX24116_REG_QUALITY0 (0xd5)
70 71 72 73 74 75 76 77
#define CX24116_REG_BER0    (0xc9)
#define CX24116_REG_BER8    (0xc8)
#define CX24116_REG_BER16   (0xc7)
#define CX24116_REG_BER24   (0xc6)
#define CX24116_REG_UCB0    (0xcb)
#define CX24116_REG_UCB8    (0xca)
#define CX24116_REG_CLKDIV  (0xf3)
#define CX24116_REG_RATEDIV (0xf9)
78 79 80

/* configured fec (not tuned) or actual FEC (tuned) 1=1/2 2=2/3 etc */
#define CX24116_REG_FECSTATUS (0x9c)
81 82

/* FECSTATUS bits */
83 84 85 86 87
/* mask to determine configured fec (not tuned) or actual fec (tuned) */
#define CX24116_FEC_FECMASK   (0x1f)

/* Select DVB-S demodulator, else DVB-S2 */
#define CX24116_FEC_DVBS      (0x20)
88
#define CX24116_FEC_UNKNOWN   (0x40)    /* Unknown/unused */
89 90 91

/* Pilot mode requested when tuning else always reset when tuned */
#define CX24116_FEC_PILOT     (0x80)
92 93 94 95

/* arg buffer size */
#define CX24116_ARGLEN (0x1e)

96 97 98 99 100 101
/* rolloff */
#define CX24116_ROLLOFF_020 (0x00)
#define CX24116_ROLLOFF_025 (0x01)
#define CX24116_ROLLOFF_035 (0x02)

/* pilot bit */
102 103
#define CX24116_PILOT_OFF (0x00)
#define CX24116_PILOT_ON (0x40)
104 105 106 107 108 109 110 111

/* signal status */
#define CX24116_HAS_SIGNAL   (0x01)
#define CX24116_HAS_CARRIER  (0x02)
#define CX24116_HAS_VITERBI  (0x04)
#define CX24116_HAS_SYNCLOCK (0x08)
#define CX24116_HAS_UNKNOWN1 (0x10)
#define CX24116_HAS_UNKNOWN2 (0x20)
112
#define CX24116_STATUS_MASK  (0x0f)
113 114 115 116 117 118
#define CX24116_SIGNAL_MASK  (0xc0)

#define CX24116_DISEQC_TONEOFF   (0)    /* toneburst never sent */
#define CX24116_DISEQC_TONECACHE (1)    /* toneburst cached     */
#define CX24116_DISEQC_MESGCACHE (2)    /* message cached       */

119 120 121 122 123 124 125 126 127 128 129 130
/* arg offset for DiSEqC */
#define CX24116_DISEQC_BURST  (1)
#define CX24116_DISEQC_ARG2_2 (2)   /* unknown value=2 */
#define CX24116_DISEQC_ARG3_0 (3)   /* unknown value=0 */
#define CX24116_DISEQC_ARG4_0 (4)   /* unknown value=0 */
#define CX24116_DISEQC_MSGLEN (5)
#define CX24116_DISEQC_MSGOFS (6)

/* DiSEqC burst */
#define CX24116_DISEQC_MINI_A (0)
#define CX24116_DISEQC_MINI_B (1)

131 132
/* DiSEqC tone burst */
static int toneburst = 1;
133
module_param(toneburst, int, 0644);
134 135
MODULE_PARM_DESC(toneburst, "DiSEqC toneburst 0=OFF, 1=TONE CACHE, "\
	"2=MESSAGE CACHE (default:1)");
136

137
/* SNR measurements */
138 139
static int esno_snr;
module_param(esno_snr, int, 0644);
140 141
MODULE_PARM_DESC(debug, "SNR return units, 0=PERCENTAGE 0-100, "\
	"1=ESNO(db * 10) (default:0)");
142

143
enum cmds {
144
	CMD_SET_VCO     = 0x10,
145
	CMD_TUNEREQUEST = 0x11,
146 147 148 149 150 151
	CMD_MPEGCONFIG  = 0x13,
	CMD_TUNERINIT   = 0x14,
	CMD_BANDWIDTH   = 0x15,
	CMD_GETAGC      = 0x19,
	CMD_LNBCONFIG   = 0x20,
	CMD_LNBSEND     = 0x21, /* Formerly CMD_SEND_DISEQC */
152
	CMD_LNBDCLEVEL  = 0x22,
153
	CMD_SET_TONE    = 0x23,
154 155 156
	CMD_UPDFWVERS   = 0x35,
	CMD_TUNERSLEEP  = 0x36,
	CMD_AGCCONTROL  = 0x3b, /* Unknown */
157 158 159
};

/* The Demod/Tuner can't easily provide these, we cache them */
160
struct cx24116_tuning {
161 162 163 164 165
	u32 frequency;
	u32 symbol_rate;
	fe_spectral_inversion_t inversion;
	fe_code_rate_t fec;

166
	fe_delivery_system_t delsys;
167
	fe_modulation_t modulation;
168 169
	fe_pilot_t pilot;
	fe_rolloff_t rolloff;
170 171 172 173 174

	/* Demod values */
	u8 fec_val;
	u8 fec_mask;
	u8 inversion_val;
175
	u8 pilot_val;
176
	u8 rolloff_val;
177 178 179
};

/* Basic commands that are sent to the firmware */
180
struct cx24116_cmd {
181 182 183 184
	u8 len;
	u8 args[CX24116_ARGLEN];
};

185 186 187
struct cx24116_state {
	struct i2c_adapter *i2c;
	const struct cx24116_config *config;
188 189 190 191 192 193 194 195

	struct dvb_frontend frontend;

	struct cx24116_tuning dcur;
	struct cx24116_tuning dnxt;

	u8 skip_fw_load;
	u8 burst;
196
	struct cx24116_cmd dsec_cmd;
197 198
};

199
static int cx24116_writereg(struct cx24116_state *state, int reg, int data)
200 201 202 203 204 205
{
	u8 buf[] = { reg, data };
	struct i2c_msg msg = { .addr = state->config->demod_address,
		.flags = 0, .buf = buf, .len = 2 };
	int err;

206
	if (debug > 1)
207
		printk("cx24116: %s: write reg 0x%02x, value 0x%02x\n",
208
			__func__, reg, data);
209

210 211
	err = i2c_transfer(state->i2c, &msg, 1);
	if (err != 1) {
212
		printk(KERN_ERR "%s: writereg error(err == %i, reg == 0x%02x,"
213 214 215 216 217 218 219 220
			 " value == 0x%02x)\n", __func__, err, reg, data);
		return -EREMOTEIO;
	}

	return 0;
}

/* Bulk byte writes to a single I2C address, for 32k firmware load */
221
static int cx24116_writeregN(struct cx24116_state *state, int reg,
222
			     const u8 *data, u16 len)
223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242
{
	int ret = -EREMOTEIO;
	struct i2c_msg msg;
	u8 *buf;

	buf = kmalloc(len + 1, GFP_KERNEL);
	if (buf == NULL) {
		printk("Unable to kmalloc\n");
		ret = -ENOMEM;
		goto error;
	}

	*(buf) = reg;
	memcpy(buf + 1, data, len);

	msg.addr = state->config->demod_address;
	msg.flags = 0;
	msg.buf = buf;
	msg.len = len + 1;

243
	if (debug > 1)
244
		printk(KERN_INFO "cx24116: %s:  write regN 0x%02x, len = %d\n",
245
			__func__, reg, len);
246

247 248
	ret = i2c_transfer(state->i2c, &msg, 1);
	if (ret != 1) {
249
		printk(KERN_ERR "%s: writereg error(err == %i, reg == 0x%02x\n",
250 251 252 253 254 255 256 257 258 259
			 __func__, ret, reg);
		ret = -EREMOTEIO;
	}

error:
	kfree(buf);

	return ret;
}

260
static int cx24116_readreg(struct cx24116_state *state, u8 reg)
261 262 263 264 265
{
	int ret;
	u8 b0[] = { reg };
	u8 b1[] = { 0 };
	struct i2c_msg msg[] = {
266 267 268 269
		{ .addr = state->config->demod_address, .flags = 0,
			.buf = b0, .len = 1 },
		{ .addr = state->config->demod_address, .flags = I2C_M_RD,
			.buf = b1, .len = 1 }
270 271 272 273 274
	};

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

	if (ret != 2) {
275 276
		printk(KERN_ERR "%s: reg=0x%x (error=%d)\n",
			__func__, reg, ret);
277 278 279
		return ret;
	}

280
	if (debug > 1)
281
		printk(KERN_INFO "cx24116: read reg 0x%02x, value 0x%02x\n",
282
			reg, b1[0]);
283 284 285 286

	return b1[0];
}

287 288
static int cx24116_set_inversion(struct cx24116_state *state,
	fe_spectral_inversion_t inversion)
289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310
{
	dprintk("%s(%d)\n", __func__, inversion);

	switch (inversion) {
	case INVERSION_OFF:
		state->dnxt.inversion_val = 0x00;
		break;
	case INVERSION_ON:
		state->dnxt.inversion_val = 0x04;
		break;
	case INVERSION_AUTO:
		state->dnxt.inversion_val = 0x0C;
		break;
	default:
		return -EINVAL;
	}

	state->dnxt.inversion = inversion;

	return 0;
}

311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335
/*
 * modfec (modulation and FEC)
 * ===========================
 *
 * MOD          FEC             mask/val    standard
 * ----         --------        ----------- --------
 * QPSK         FEC_1_2         0x02 0x02+X DVB-S
 * QPSK         FEC_2_3         0x04 0x02+X DVB-S
 * QPSK         FEC_3_4         0x08 0x02+X DVB-S
 * QPSK         FEC_4_5         0x10 0x02+X DVB-S (?)
 * QPSK         FEC_5_6         0x20 0x02+X DVB-S
 * QPSK         FEC_6_7         0x40 0x02+X DVB-S
 * QPSK         FEC_7_8         0x80 0x02+X DVB-S
 * QPSK         FEC_8_9         0x01 0x02+X DVB-S (?) (NOT SUPPORTED?)
 * QPSK         AUTO            0xff 0x02+X DVB-S
 *
 * For DVB-S high byte probably represents FEC
 * and low byte selects the modulator. The high
 * byte is search range mask. Bit 5 may turn
 * on DVB-S and remaining bits represent some
 * kind of calibration (how/what i do not know).
 *
 * Eg.(2/3) szap "Zone Horror"
 *
 * mask/val = 0x04, 0x20
336
 * status 1f | signal c3c0 | snr a333 | ber 00000098 | unc 0 | FE_HAS_LOCK
337 338
 *
 * mask/val = 0x04, 0x30
339
 * status 1f | signal c3c0 | snr a333 | ber 00000000 | unc 0 | FE_HAS_LOCK
340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370
 *
 * After tuning FECSTATUS contains actual FEC
 * in use numbered 1 through to 8 for 1/2 .. 2/3 etc
 *
 * NBC=NOT/NON BACKWARD COMPATIBLE WITH DVB-S (DVB-S2 only)
 *
 * NBC-QPSK     FEC_1_2         0x00, 0x04      DVB-S2
 * NBC-QPSK     FEC_3_5         0x00, 0x05      DVB-S2
 * NBC-QPSK     FEC_2_3         0x00, 0x06      DVB-S2
 * NBC-QPSK     FEC_3_4         0x00, 0x07      DVB-S2
 * NBC-QPSK     FEC_4_5         0x00, 0x08      DVB-S2
 * NBC-QPSK     FEC_5_6         0x00, 0x09      DVB-S2
 * NBC-QPSK     FEC_8_9         0x00, 0x0a      DVB-S2
 * NBC-QPSK     FEC_9_10        0x00, 0x0b      DVB-S2
 *
 * NBC-8PSK     FEC_3_5         0x00, 0x0c      DVB-S2
 * NBC-8PSK     FEC_2_3         0x00, 0x0d      DVB-S2
 * NBC-8PSK     FEC_3_4         0x00, 0x0e      DVB-S2
 * NBC-8PSK     FEC_5_6         0x00, 0x0f      DVB-S2
 * NBC-8PSK     FEC_8_9         0x00, 0x10      DVB-S2
 * NBC-8PSK     FEC_9_10        0x00, 0x11      DVB-S2
 *
 * For DVB-S2 low bytes selects both modulator
 * and FEC. High byte is meaningless here. To
 * set pilot, bit 6 (0x40) is set. When inspecting
 * FECSTATUS bit 7 (0x80) represents the pilot
 * selection whilst not tuned. When tuned, actual FEC
 * in use is found in FECSTATUS as per above. Pilot
 * value is reset.
 */

371 372 373 374
/* A table of modulation, fec and configuration bytes for the demod.
 * Not all S2 mmodulation schemes are support and not all rates with
 * a scheme are support. Especially, no auto detect when in S2 mode.
 */
375
static struct cx24116_modfec {
376
	fe_delivery_system_t delivery_system;
377 378 379 380 381 382
	fe_modulation_t modulation;
	fe_code_rate_t fec;
	u8 mask;	/* In DVBS mode this is used to autodetect */
	u8 val;		/* Passed to the firmware to indicate mode selection */
} CX24116_MODFEC_MODES[] = {
 /* QPSK. For unknown rates we set hardware to auto detect 0xfe 0x30 */
383 384

 /*mod   fec       mask  val */
385 386 387 388 389 390 391 392 393 394
 { SYS_DVBS, QPSK, FEC_NONE, 0xfe, 0x30 },
 { SYS_DVBS, QPSK, FEC_1_2,  0x02, 0x2e }, /* 00000010 00101110 */
 { SYS_DVBS, QPSK, FEC_2_3,  0x04, 0x2f }, /* 00000100 00101111 */
 { SYS_DVBS, QPSK, FEC_3_4,  0x08, 0x30 }, /* 00001000 00110000 */
 { SYS_DVBS, QPSK, FEC_4_5,  0xfe, 0x30 }, /* 000?0000 ?        */
 { SYS_DVBS, QPSK, FEC_5_6,  0x20, 0x31 }, /* 00100000 00110001 */
 { SYS_DVBS, QPSK, FEC_6_7,  0xfe, 0x30 }, /* 0?000000 ?        */
 { SYS_DVBS, QPSK, FEC_7_8,  0x80, 0x32 }, /* 10000000 00110010 */
 { SYS_DVBS, QPSK, FEC_8_9,  0xfe, 0x30 }, /* 0000000? ?        */
 { SYS_DVBS, QPSK, FEC_AUTO, 0xfe, 0x30 },
395
 /* NBC-QPSK */
396 397 398 399 400 401 402 403
 { SYS_DVBS2, QPSK, FEC_1_2,  0x00, 0x04 },
 { SYS_DVBS2, QPSK, FEC_3_5,  0x00, 0x05 },
 { SYS_DVBS2, QPSK, FEC_2_3,  0x00, 0x06 },
 { SYS_DVBS2, QPSK, FEC_3_4,  0x00, 0x07 },
 { SYS_DVBS2, QPSK, FEC_4_5,  0x00, 0x08 },
 { SYS_DVBS2, QPSK, FEC_5_6,  0x00, 0x09 },
 { SYS_DVBS2, QPSK, FEC_8_9,  0x00, 0x0a },
 { SYS_DVBS2, QPSK, FEC_9_10, 0x00, 0x0b },
404
 /* 8PSK */
405 406 407 408 409 410
 { SYS_DVBS2, PSK_8, FEC_3_5,  0x00, 0x0c },
 { SYS_DVBS2, PSK_8, FEC_2_3,  0x00, 0x0d },
 { SYS_DVBS2, PSK_8, FEC_3_4,  0x00, 0x0e },
 { SYS_DVBS2, PSK_8, FEC_5_6,  0x00, 0x0f },
 { SYS_DVBS2, PSK_8, FEC_8_9,  0x00, 0x10 },
 { SYS_DVBS2, PSK_8, FEC_9_10, 0x00, 0x11 },
411 412 413 414
 /*
  * `val' can be found in the FECSTATUS register when tuning.
  * FECSTATUS will give the actual FEC in use if tuning was successful.
  */
415 416
};

417
static int cx24116_lookup_fecmod(struct cx24116_state *state,
418
	fe_delivery_system_t d, fe_modulation_t m, fe_code_rate_t f)
419 420 421
{
	int i, ret = -EOPNOTSUPP;

422 423
	dprintk("%s(0x%02x,0x%02x)\n", __func__, m, f);

424
	for (i = 0; i < ARRAY_SIZE(CX24116_MODFEC_MODES); i++) {
425 426
		if ((d == CX24116_MODFEC_MODES[i].delivery_system) &&
			(m == CX24116_MODFEC_MODES[i].modulation) &&
427
			(f == CX24116_MODFEC_MODES[i].fec)) {
428 429 430 431 432 433 434 435
				ret = i;
				break;
			}
	}

	return ret;
}

436
static int cx24116_set_fec(struct cx24116_state *state,
437
	fe_delivery_system_t delsys, fe_modulation_t mod, fe_code_rate_t fec)
438 439
{
	int ret = 0;
440 441

	dprintk("%s(0x%02x,0x%02x)\n", __func__, mod, fec);
442

443
	ret = cx24116_lookup_fecmod(state, delsys, mod, fec);
444

445
	if (ret < 0)
446 447
		return ret;

448
	state->dnxt.fec = fec;
449 450
	state->dnxt.fec_val = CX24116_MODFEC_MODES[ret].val;
	state->dnxt.fec_mask = CX24116_MODFEC_MODES[ret].mask;
451 452
	dprintk("%s() mask/val = 0x%02x/0x%02x\n", __func__,
		state->dnxt.fec_mask, state->dnxt.fec_val);
453 454 455 456

	return 0;
}

457
static int cx24116_set_symbolrate(struct cx24116_state *state, u32 rate)
458
{
459
	dprintk("%s(%d)\n", __func__, rate);
460

461 462 463 464 465 466
	/*  check if symbol rate is within limits */
	if ((rate > state->frontend.ops.info.symbol_rate_max) ||
	    (rate < state->frontend.ops.info.symbol_rate_min)) {
		dprintk("%s() unsupported symbol_rate = %d\n", __func__, rate);
		return -EOPNOTSUPP;
	}
467 468

	state->dnxt.symbol_rate = rate;
469
	dprintk("%s() symbol_rate = %d\n", __func__, rate);
470

471
	return 0;
472 473
}

474 475
static int cx24116_load_firmware(struct dvb_frontend *fe,
	const struct firmware *fw);
476

477
static int cx24116_firmware_ondemand(struct dvb_frontend *fe)
478 479 480 481 482
{
	struct cx24116_state *state = fe->demodulator_priv;
	const struct firmware *fw;
	int ret = 0;

483
	dprintk("%s()\n", __func__);
484

485
	if (cx24116_readreg(state, 0x20) > 0) {
486 487 488 489 490

		if (state->skip_fw_load)
			return 0;

		/* Load firmware */
491 492 493 494
		/* request the firmware, this will block until loaded */
		printk(KERN_INFO "%s: Waiting for firmware upload (%s)...\n",
			__func__, CX24116_DEFAULT_FIRMWARE);
		ret = request_firmware(&fw, CX24116_DEFAULT_FIRMWARE,
495
			state->i2c->dev.parent);
496 497
		printk(KERN_INFO "%s: Waiting for firmware upload(2)...\n",
			__func__);
498
		if (ret) {
499 500
			printk(KERN_ERR "%s: No firmware uploaded "
				"(timeout or file not found?)\n", __func__);
501 502 503
			return ret;
		}

504 505
		/* Make sure we don't recurse back through here
		 * during loading */
506 507 508 509
		state->skip_fw_load = 1;

		ret = cx24116_load_firmware(fe, fw);
		if (ret)
510 511
			printk(KERN_ERR "%s: Writing firmware to device failed\n",
				__func__);
512 513 514

		release_firmware(fw);

515 516
		printk(KERN_INFO "%s: Firmware upload %s\n", __func__,
			ret == 0 ? "complete" : "failed");
517 518 519 520 521 522 523 524

		/* Ensure firmware is always loaded if required */
		state->skip_fw_load = 0;
	}

	return ret;
}

525 526 527
/* Take a basic firmware command structure, format it
 * and forward it for processing
 */
528
static int cx24116_cmd_execute(struct dvb_frontend *fe, struct cx24116_cmd *cmd)
529 530 531 532 533 534 535
{
	struct cx24116_state *state = fe->demodulator_priv;
	int i, ret;

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

	/* Load the firmware if required */
536 537
	ret = cx24116_firmware_ondemand(fe);
	if (ret != 0) {
538 539
		printk(KERN_ERR "%s(): Unable initialise the firmware\n",
			__func__);
540 541 542 543
		return ret;
	}

	/* Write the command */
544
	for (i = 0; i < cmd->len ; i++) {
545 546 547 548 549
		dprintk("%s: 0x%02x == 0x%02x\n", __func__, i, cmd->args[i]);
		cx24116_writereg(state, i, cmd->args[i]);
	}

	/* Start execution and wait for cmd to terminate */
550
	cx24116_writereg(state, CX24116_REG_EXECUTE, 0x01);
551
	while (cx24116_readreg(state, CX24116_REG_EXECUTE)) {
552
		msleep(10);
553
		if (i++ > 64) {
554 555 556 557
			/* Avoid looping forever if the firmware does
				not respond */
			printk(KERN_WARNING "%s() Firmware not responding\n",
				__func__);
558 559 560 561 562 563
			return -EREMOTEIO;
		}
	}
	return 0;
}

564 565
static int cx24116_load_firmware(struct dvb_frontend *fe,
	const struct firmware *fw)
566
{
567
	struct cx24116_state *state = fe->demodulator_priv;
568
	struct cx24116_cmd cmd;
569 570
	int i, ret;
	unsigned char vers[4];
571 572

	dprintk("%s\n", __func__);
573 574 575 576 577 578
	dprintk("Firmware is %zu bytes (%02x %02x .. %02x %02x)\n",
			fw->size,
			fw->data[0],
			fw->data[1],
			fw->data[fw->size-2],
			fw->data[fw->size-1]);
579 580 581 582 583 584 585

	/* Toggle 88x SRST pin to reset demod */
	if (state->config->reset_device)
		state->config->reset_device(fe);

	/* Begin the firmware load process */
	/* Prepare the demod, load the firmware, cleanup after load */
586 587 588

	/* Init PLL */
	cx24116_writereg(state, 0xE5, 0x00);
589
	cx24116_writereg(state, 0xF1, 0x08);
590 591 592 593 594 595 596 597 598
	cx24116_writereg(state, 0xF2, 0x13);

	/* Start PLL */
	cx24116_writereg(state, 0xe0, 0x03);
	cx24116_writereg(state, 0xe0, 0x00);

	/* Unknown */
	cx24116_writereg(state, CX24116_REG_CLKDIV, 0x46);
	cx24116_writereg(state, CX24116_REG_RATEDIV, 0x00);
599

600
	/* Unknown */
601 602 603 604 605 606 607 608 609 610 611 612
	cx24116_writereg(state, 0xF0, 0x03);
	cx24116_writereg(state, 0xF4, 0x81);
	cx24116_writereg(state, 0xF5, 0x00);
	cx24116_writereg(state, 0xF6, 0x00);

	/* write the entire firmware as one transaction */
	cx24116_writeregN(state, 0xF7, fw->data, fw->size);

	cx24116_writereg(state, 0xF4, 0x10);
	cx24116_writereg(state, 0xF0, 0x00);
	cx24116_writereg(state, 0xF8, 0x06);

613 614
	/* Firmware CMD 10: VCO config */
	cmd.args[0x00] = CMD_SET_VCO;
615 616 617 618 619 620 621 622 623
	cmd.args[0x01] = 0x05;
	cmd.args[0x02] = 0xdc;
	cmd.args[0x03] = 0xda;
	cmd.args[0x04] = 0xae;
	cmd.args[0x05] = 0xaa;
	cmd.args[0x06] = 0x04;
	cmd.args[0x07] = 0x9d;
	cmd.args[0x08] = 0xfc;
	cmd.args[0x09] = 0x06;
624
	cmd.len = 0x0a;
625 626 627 628
	ret = cx24116_cmd_execute(fe, &cmd);
	if (ret != 0)
		return ret;

629
	cx24116_writereg(state, CX24116_REG_SSTATUS, 0x00);
630

631 632
	/* Firmware CMD 14: Tuner config */
	cmd.args[0x00] = CMD_TUNERINIT;
633 634
	cmd.args[0x01] = 0x00;
	cmd.args[0x02] = 0x00;
635
	cmd.len = 0x03;
636 637 638 639 640 641
	ret = cx24116_cmd_execute(fe, &cmd);
	if (ret != 0)
		return ret;

	cx24116_writereg(state, 0xe5, 0x00);

642 643
	/* Firmware CMD 13: MPEG config */
	cmd.args[0x00] = CMD_MPEGCONFIG;
644 645 646
	cmd.args[0x01] = 0x01;
	cmd.args[0x02] = 0x75;
	cmd.args[0x03] = 0x00;
647 648 649 650
	if (state->config->mpg_clk_pos_pol)
		cmd.args[0x04] = state->config->mpg_clk_pos_pol;
	else
		cmd.args[0x04] = 0x02;
651
	cmd.args[0x05] = 0x00;
652
	cmd.len = 0x06;
653 654 655 656
	ret = cx24116_cmd_execute(fe, &cmd);
	if (ret != 0)
		return ret;

657 658
	/* Firmware CMD 35: Get firmware version */
	cmd.args[0x00] = CMD_UPDFWVERS;
659 660
	cmd.len = 0x02;
	for (i = 0; i < 4; i++) {
661 662 663 664
		cmd.args[0x01] = i;
		ret = cx24116_cmd_execute(fe, &cmd);
		if (ret != 0)
			return ret;
665
		vers[i] = cx24116_readreg(state, CX24116_REG_MAILBOX);
666
	}
667
	printk(KERN_INFO "%s: FW version %i.%i.%i.%i\n", __func__,
668 669
		vers[0], vers[1], vers[2], vers[3]);

670 671 672
	return 0;
}

673
static int cx24116_read_status(struct dvb_frontend *fe, fe_status_t *status)
674 675 676
{
	struct cx24116_state *state = fe->demodulator_priv;

677 678
	int lock = cx24116_readreg(state, CX24116_REG_SSTATUS) &
		CX24116_STATUS_MASK;
679 680 681 682 683

	dprintk("%s: status = 0x%02x\n", __func__, lock);

	*status = 0;

684
	if (lock & CX24116_HAS_SIGNAL)
685
		*status |= FE_HAS_SIGNAL;
686
	if (lock & CX24116_HAS_CARRIER)
687
		*status |= FE_HAS_CARRIER;
688
	if (lock & CX24116_HAS_VITERBI)
689
		*status |= FE_HAS_VITERBI;
690
	if (lock & CX24116_HAS_SYNCLOCK)
691 692 693 694 695
		*status |= FE_HAS_SYNC | FE_HAS_LOCK;

	return 0;
}

696
static int cx24116_read_ber(struct dvb_frontend *fe, u32 *ber)
697
{
698 699
	struct cx24116_state *state = fe->demodulator_priv;

700
	dprintk("%s()\n", __func__);
701

702 703 704 705
	*ber =  (cx24116_readreg(state, CX24116_REG_BER24) << 24) |
		(cx24116_readreg(state, CX24116_REG_BER16) << 16) |
		(cx24116_readreg(state, CX24116_REG_BER8)  << 8)  |
		 cx24116_readreg(state, CX24116_REG_BER0);
706 707 708 709

	return 0;
}

710
/* TODO Determine function and scale appropriately */
711 712
static int cx24116_read_signal_strength(struct dvb_frontend *fe,
	u16 *signal_strength)
713 714
{
	struct cx24116_state *state = fe->demodulator_priv;
715 716 717
	struct cx24116_cmd cmd;
	int ret;
	u16 sig_reading;
718 719 720

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

721 722
	/* Firmware CMD 19: Get AGC */
	cmd.args[0x00] = CMD_GETAGC;
723
	cmd.len = 0x01;
724 725 726
	ret = cx24116_cmd_execute(fe, &cmd);
	if (ret != 0)
		return ret;
727

728 729 730 731 732
	sig_reading =
		(cx24116_readreg(state,
			CX24116_REG_SSTATUS) & CX24116_SIGNAL_MASK) |
		(cx24116_readreg(state, CX24116_REG_SIGNAL) << 6);
	*signal_strength = 0 - sig_reading;
733

734 735
	dprintk("%s: raw / cooked = 0x%04x / 0x%04x\n",
		__func__, sig_reading, *signal_strength);
736 737 738 739

	return 0;
}

740
/* SNR (0..100)% = (sig & 0xf0) * 10 + (sig & 0x0f) * 10 / 16 */
741
static int cx24116_read_snr_pct(struct dvb_frontend *fe, u16 *snr)
742
{
743 744 745
	struct cx24116_state *state = fe->demodulator_priv;
	u8 snr_reading;
	static const u32 snr_tab[] = { /* 10 x Table (rounded up) */
746 747 748 749
		0x00000, 0x0199A, 0x03333, 0x04ccD, 0x06667,
		0x08000, 0x0999A, 0x0b333, 0x0cccD, 0x0e667,
		0x10000, 0x1199A, 0x13333, 0x14ccD, 0x16667,
		0x18000 };
750

751
	dprintk("%s()\n", __func__);
752

753
	snr_reading = cx24116_readreg(state, CX24116_REG_QUALITY0);
754

755
	if (snr_reading >= 0xa0 /* 100% */)
756 757
		*snr = 0xffff;
	else
758 759
		*snr = snr_tab[(snr_reading & 0xf0) >> 4] +
			(snr_tab[(snr_reading & 0x0f)] >> 4);
760 761 762

	dprintk("%s: raw / cooked = 0x%02x / 0x%04x\n", __func__,
		snr_reading, *snr);
763 764 765 766

	return 0;
}

767 768 769 770
/* The reelbox patches show the value in the registers represents
 * ESNO, from 0->30db (values 0->300). We provide this value by
 * default.
 */
771
static int cx24116_read_snr_esno(struct dvb_frontend *fe, u16 *snr)
772 773 774 775 776 777 778 779 780 781 782 783 784
{
	struct cx24116_state *state = fe->demodulator_priv;

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

	*snr = cx24116_readreg(state, CX24116_REG_QUALITY8) << 8 |
		cx24116_readreg(state, CX24116_REG_QUALITY0);

	dprintk("%s: raw 0x%04x\n", __func__, *snr);

	return 0;
}

785
static int cx24116_read_snr(struct dvb_frontend *fe, u16 *snr)
786 787 788 789 790 791 792
{
	if (esno_snr == 1)
		return cx24116_read_snr_esno(fe, snr);
	else
		return cx24116_read_snr_pct(fe, snr);
}

793
static int cx24116_read_ucblocks(struct dvb_frontend *fe, u32 *ucblocks)
794
{
795 796
	struct cx24116_state *state = fe->demodulator_priv;

797
	dprintk("%s()\n", __func__);
798

799
	*ucblocks = (cx24116_readreg(state, CX24116_REG_UCB8) << 8) |
800
		cx24116_readreg(state, CX24116_REG_UCB0);
801 802 803 804 805

	return 0;
}

/* Overwrite the current tuning params, we are about to tune */
806
static void cx24116_clone_params(struct dvb_frontend *fe)
807 808 809 810 811
{
	struct cx24116_state *state = fe->demodulator_priv;
	memcpy(&state->dcur, &state->dnxt, sizeof(state->dcur));
}

812
/* Wait for LNB */
813
static int cx24116_wait_for_lnb(struct dvb_frontend *fe)
814 815 816 817 818 819 820 821
{
	struct cx24116_state *state = fe->demodulator_priv;
	int i;

	dprintk("%s() qstatus = 0x%02x\n", __func__,
		cx24116_readreg(state, CX24116_REG_QSTATUS));

	/* Wait for up to 300 ms */
822
	for (i = 0; i < 30 ; i++) {
823 824 825 826 827 828 829 830 831 832
		if (cx24116_readreg(state, CX24116_REG_QSTATUS) & 0x20)
			return 0;
		msleep(10);
	}

	dprintk("%s(): LNB not ready\n", __func__);

	return -ETIMEDOUT; /* -EBUSY ? */
}

833 834 835 836 837 838 839 840 841 842 843 844 845 846 847 848 849 850 851 852 853 854 855 856 857 858 859 860
static int cx24116_set_voltage(struct dvb_frontend *fe,
	fe_sec_voltage_t voltage)
{
	struct cx24116_cmd cmd;
	int ret;

	dprintk("%s: %s\n", __func__,
		voltage == SEC_VOLTAGE_13 ? "SEC_VOLTAGE_13" :
		voltage == SEC_VOLTAGE_18 ? "SEC_VOLTAGE_18" : "??");

	/* Wait for LNB ready */
	ret = cx24116_wait_for_lnb(fe);
	if (ret != 0)
		return ret;

	/* Wait for voltage/min repeat delay */
	msleep(100);

	cmd.args[0x00] = CMD_LNBDCLEVEL;
	cmd.args[0x01] = (voltage == SEC_VOLTAGE_18 ? 0x01 : 0x00);
	cmd.len = 0x02;

	/* Min delay time before DiSEqC send */
	msleep(15);

	return cx24116_cmd_execute(fe, &cmd);
}

861 862
static int cx24116_set_tone(struct dvb_frontend *fe,
	fe_sec_tone_mode_t tone)
863 864 865 866 867
{
	struct cx24116_cmd cmd;
	int ret;

	dprintk("%s(%d)\n", __func__, tone);
868
	if ((tone != SEC_TONE_ON) && (tone != SEC_TONE_OFF)) {
869
		printk(KERN_ERR "%s: Invalid, tone=%d\n", __func__, tone);
870 871 872
		return -EINVAL;
	}

873 874
	/* Wait for LNB ready */
	ret = cx24116_wait_for_lnb(fe);
875
	if (ret != 0)
876 877 878 879 880
		return ret;

	/* Min delay time after DiSEqC send */
	msleep(15); /* XXX determine is FW does this, see send_diseqc/burst */

881 882 883 884 885 886 887 888 889 890 891
	/* Now we set the tone */
	cmd.args[0x00] = CMD_SET_TONE;
	cmd.args[0x01] = 0x00;
	cmd.args[0x02] = 0x00;

	switch (tone) {
	case SEC_TONE_ON:
		dprintk("%s: setting tone on\n", __func__);
		cmd.args[0x03] = 0x01;
		break;
	case SEC_TONE_OFF:
892
		dprintk("%s: setting tone off\n", __func__);
893 894 895
		cmd.args[0x03] = 0x00;
		break;
	}
896
	cmd.len = 0x04;
897

898 899 900
	/* Min delay time before DiSEqC send */
	msleep(15); /* XXX determine is FW does this, see send_diseqc/burst */

901 902 903 904
	return cx24116_cmd_execute(fe, &cmd);
}

/* Initialise DiSEqC */
905
static int cx24116_diseqc_init(struct dvb_frontend *fe)
906 907
{
	struct cx24116_state *state = fe->demodulator_priv;
908 909 910 911 912 913 914 915 916 917 918 919
	struct cx24116_cmd cmd;
	int ret;

	/* Firmware CMD 20: LNB/DiSEqC config */
	cmd.args[0x00] = CMD_LNBCONFIG;
	cmd.args[0x01] = 0x00;
	cmd.args[0x02] = 0x10;
	cmd.args[0x03] = 0x00;
	cmd.args[0x04] = 0x8f;
	cmd.args[0x05] = 0x28;
	cmd.args[0x06] = (toneburst == CX24116_DISEQC_TONEOFF) ? 0x00 : 0x01;
	cmd.args[0x07] = 0x01;
920
	cmd.len = 0x08;
921 922 923 924 925 926 927 928 929 930 931 932 933
	ret = cx24116_cmd_execute(fe, &cmd);
	if (ret != 0)
		return ret;

	/* Prepare a DiSEqC command */
	state->dsec_cmd.args[0x00] = CMD_LNBSEND;

	/* DiSEqC burst */
	state->dsec_cmd.args[CX24116_DISEQC_BURST]  = CX24116_DISEQC_MINI_A;

	/* Unknown */
	state->dsec_cmd.args[CX24116_DISEQC_ARG2_2] = 0x02;
	state->dsec_cmd.args[CX24116_DISEQC_ARG3_0] = 0x00;
934 935
	/* Continuation flag? */
	state->dsec_cmd.args[CX24116_DISEQC_ARG4_0] = 0x00;
936

937 938 939 940
	/* DiSEqC message length */
	state->dsec_cmd.args[CX24116_DISEQC_MSGLEN] = 0x00;

	/* Command length */
941
	state->dsec_cmd.len = CX24116_DISEQC_MSGOFS;
942 943 944 945 946

	return 0;
}

/* Send DiSEqC message with derived burst (hack) || previous burst */
947 948
static int cx24116_send_diseqc_msg(struct dvb_frontend *fe,
	struct dvb_diseqc_master_cmd *d)
949 950 951 952 953 954
{
	struct cx24116_state *state = fe->demodulator_priv;
	int i, ret;

	/* Dump DiSEqC message */
	if (debug) {
955
		printk(KERN_INFO "cx24116: %s(", __func__);
956
		for (i = 0 ; i < d->msg_len ;) {
957
			printk(KERN_INFO "0x%02x", d->msg[i]);
958
			if (++i < d->msg_len)
959
				printk(KERN_INFO ", ");
960
		}
961
		printk(") toneburst=%d\n", toneburst);
962 963
	}

964
	/* Validate length */
965
	if (d->msg_len > (CX24116_ARGLEN - CX24116_DISEQC_MSGOFS))
966 967 968 969
		return -EINVAL;

	/* DiSEqC message */
	for (i = 0; i < d->msg_len; i++)
970 971 972 973 974 975
		state->dsec_cmd.args[CX24116_DISEQC_MSGOFS + i] = d->msg[i];

	/* DiSEqC message length */
	state->dsec_cmd.args[CX24116_DISEQC_MSGLEN] = d->msg_len;

	/* Command length */
976 977
	state->dsec_cmd.len = CX24116_DISEQC_MSGOFS +
		state->dsec_cmd.args[CX24116_DISEQC_MSGLEN];
978 979

	/* DiSEqC toneburst */
980
	if (toneburst == CX24116_DISEQC_MESGCACHE)
981 982 983
		/* Message is cached */
		return 0;

984
	else if (toneburst == CX24116_DISEQC_TONEOFF)
985 986 987
		/* Message is sent without burst */
		state->dsec_cmd.args[CX24116_DISEQC_BURST] = 0;

988
	else if (toneburst == CX24116_DISEQC_TONECACHE) {
989 990 991 992 993 994 995 996 997 998
		/*
		 * Message is sent with derived else cached burst
		 *
		 * WRITE PORT GROUP COMMAND 38
		 *
		 * 0/A/A: E0 10 38 F0..F3
		 * 1/B/B: E0 10 38 F4..F7
		 * 2/C/A: E0 10 38 F8..FB
		 * 3/D/B: E0 10 38 FC..FF
		 *
999
		 * databyte[3]= 8421:8421
1000 1001 1002 1003 1004 1005 1006
		 *              ABCD:WXYZ
		 *              CLR :SET
		 *
		 *              WX= PORT SELECT 0..3    (X=TONEBURST)
		 *              Y = VOLTAGE             (0=13V, 1=18V)
		 *              Z = BAND                (0=LOW, 1=HIGH(22K))
		 */
1007 1008 1009 1010 1011 1012
		if (d->msg_len >= 4 && d->msg[2] == 0x38)
			state->dsec_cmd.args[CX24116_DISEQC_BURST] =
				((d->msg[3] & 4) >> 2);
		if (debug)
			dprintk("%s burst=%d\n", __func__,
				state->dsec_cmd.args[CX24116_DISEQC_BURST]);
1013
	}
1014

1015 1016
	/* Wait for LNB ready */
	ret = cx24116_wait_for_lnb(fe);
1017
	if (ret != 0)
1018
		return ret;
1019

1020 1021
	/* Wait for voltage/min repeat delay */
	msleep(100);
1022

1023 1024
	/* Command */
	ret = cx24116_cmd_execute(fe, &state->dsec_cmd);
1025
	if (ret != 0)
1026 1027 1028
		return ret;
	/*
	 * Wait for send
1029 1030
	 *
	 * Eutelsat spec:
1031 1032 1033 1034 1035
	 * >15ms delay          + (XXX determine if FW does this, see set_tone)
	 *  13.5ms per byte     +
	 * >15ms delay          +
	 *  12.5ms burst        +
	 * >15ms delay            (XXX determine if FW does this, see set_tone)
1036
	 */
1037 1038
	msleep((state->dsec_cmd.args[CX24116_DISEQC_MSGLEN] << 4) +
		((toneburst == CX24116_DISEQC_TONEOFF) ? 30 : 60));
1039

1040
	return 0;
1041 1042 1043
}

/* Send DiSEqC burst */
1044 1045
static int cx24116_diseqc_send_burst(struct dvb_frontend *fe,
	fe_sec_mini_cmd_t burst)
1046 1047 1048 1049
{
	struct cx24116_state *state = fe->demodulator_priv;
	int ret;

1050
	dprintk("%s(%d) toneburst=%d\n", __func__, burst, toneburst);
1051

1052
	/* DiSEqC burst */
1053
	if (burst == SEC_MINI_A)
1054 1055 1056 1057 1058
		state->dsec_cmd.args[CX24116_DISEQC_BURST] =
			CX24116_DISEQC_MINI_A;
	else if (burst == SEC_MINI_B)
		state->dsec_cmd.args[CX24116_DISEQC_BURST] =
			CX24116_DISEQC_MINI_B;
1059 1060 1061
	else
		return -EINVAL;

1062
	/* DiSEqC toneburst */
1063
	if (toneburst != CX24116_DISEQC_MESGCACHE)
1064 1065
		/* Burst is cached */
		return 0;
1066

1067
	/* Burst is to be sent with cached message */
1068

1069 1070
	/* Wait for LNB ready */
	ret = cx24116_wait_for_lnb(fe);
1071
	if (ret != 0)
1072
		return ret;
1073

1074 1075
	/* Wait for voltage/min repeat delay */
	msleep(100);
1076

1077 1078
	/* Command */
	ret = cx24116_cmd_execute(fe, &state->dsec_cmd);
1079
	if (ret != 0)
1080 1081 1082 1083 1084 1085 1086 1087 1088 1089 1090 1091
		return ret;

	/*
	 * Wait for send
	 *
	 * Eutelsat spec:
	 * >15ms delay          + (XXX determine if FW does this, see set_tone)
	 *  13.5ms per byte     +
	 * >15ms delay          +
	 *  12.5ms burst        +
	 * >15ms delay            (XXX determine if FW does this, see set_tone)
	 */
1092
	msleep((state->dsec_cmd.args[CX24116_DISEQC_MSGLEN] << 4) + 60);
1093 1094

	return 0;
1095 1096
}

1097
static void cx24116_release(struct dvb_frontend *fe)
1098
{
1099 1100
	struct cx24116_state *state = fe->demodulator_priv;
	dprintk("%s\n", __func__);
1101 1102 1103 1104 1105
	kfree(state);
}

static struct dvb_frontend_ops cx24116_ops;

1106 1107
struct dvb_frontend *cx24116_attach(const struct cx24116_config *config,
	struct i2c_adapter *i2c)
1108
{
1109
	struct cx24116_state *state = NULL;
1110 1111
	int ret;

1112
	dprintk("%s\n", __func__);
1113 1114

	/* allocate memory for the internal state */
1115
	state = kzalloc(sizeof(struct cx24116_state), GFP_KERNEL);
1116
	if (state == NULL)
1117
		goto error1;
1118 1119 1120 1121 1122

	state->config = config;
	state->i2c = i2c;

	/* check if the demod is present */
1123 1124
	ret = (cx24116_readreg(state, 0xFF) << 8) |
		cx24116_readreg(state, 0xFE);
1125
	if (ret != 0x0501) {
1126
		printk(KERN_INFO "Invalid probe, probably not a CX24116 device\n");
1127
		goto error2;
1128 1129 1130
	}

	/* create dvb_frontend */
1131 1132
	memcpy(&state->frontend.ops, &cx24116_ops,
		sizeof(struct dvb_frontend_ops));
1133 1134 1135
	state->frontend.demodulator_priv = state;
	return &state->frontend;

1136
error2: kfree(state);
1137
error1: return NULL;
1138
}
1139 1140
EXPORT_SYMBOL(cx24116_attach);

1141 1142 1143 1144 1145
/*
 * Initialise or wake up device
 *
 * Power config will reset and load initial firmware if required
 */
1146
static int cx24116_initfe(struct dvb_frontend *fe)
1147
{
1148
	struct cx24116_state *state = fe->demodulator_priv;
1149 1150
	struct cx24116_cmd cmd;
	int ret;
1151

1152
	dprintk("%s()\n", __func__);
1153

1154 1155 1156 1157
	/* Power on */
	cx24116_writereg(state, 0xe0, 0);
	cx24116_writereg(state, 0xe1, 0);
	cx24116_writereg(state, 0xea, 0);
1158

1159 1160 1161
	/* Firmware CMD 36: Power config */
	cmd.args[0x00] = CMD_TUNERSLEEP;
	cmd.args[0x01] = 0;
1162
	cmd.len = 0x02;
1163
	ret = cx24116_cmd_execute(fe, &cmd);
1164
	if (ret != 0)
1165 1166
		return ret;

1167 1168 1169 1170 1171 1172
	ret = cx24116_diseqc_init(fe);
	if (ret != 0)
		return ret;

	/* HVR-4000 needs this */
	return cx24116_set_voltage(fe, SEC_VOLTAGE_13);
1173 1174
}

1175 1176 1177
/*
 * Put device to sleep
 */
1178
static int cx24116_sleep(struct dvb_frontend *fe)
1179
{
1180
	struct cx24116_state *state = fe->demodulator_priv;
1181 1182 1183
	struct cx24116_cmd cmd;
	int ret;

1184
	dprintk("%s()\n", __func__);
1185

1186 1187 1188
	/* Firmware CMD 36: Power config */
	cmd.args[0x00] = CMD_TUNERSLEEP;
	cmd.args[0x01] = 1;
1189
	cmd.len = 0x02;
1190
	ret = cx24116_cmd_execute(fe, &cmd);
1191
	if (ret != 0)
1192 1193 1194 1195 1196 1197 1198 1199
		return ret;

	/* Power off (Shutdown clocks) */
	cx24116_writereg(state, 0xea, 0xff);
	cx24116_writereg(state, 0xe1, 1);
	cx24116_writereg(state, 0xe0, 1);

	return 0;
1200 1201
}

1202 1203
static int cx24116_set_property(struct dvb_frontend *fe,
	struct dtv_property *tvp)
1204 1205 1206 1207 1208
{
	dprintk("%s(..)\n", __func__);
	return 0;
}

1209 1210
static int cx24116_get_property(struct dvb_frontend *fe,
	struct dtv_property *tvp)
1211
{
1212
	dprintk("%s(..)\n", __func__);
1213 1214 1215 1216 1217 1218
	return 0;
}

/* dvb-core told us to tune, the tv property cache will be complete,
 * it's safe for is to pull values and use them for tuning purposes.
 */
1219 1220
static int cx24116_set_frontend(struct dvb_frontend *fe,
	struct dvb_frontend_parameters *p)
1221 1222
{
	struct cx24116_state *state = fe->demodulator_priv;
1223
	struct dtv_frontend_properties *c = &fe->dtv_property_cache;
1224 1225
	struct cx24116_cmd cmd;
	fe_status_t tunerstat;
1226
	int i, status, ret, retune = 1;
1227

1228
	dprintk("%s()\n", __func__);
1229

1230 1231 1232
	switch (c->delivery_system) {
	case SYS_DVBS:
		dprintk("%s: DVB-S delivery system selected\n", __func__);
1233

1234 1235 1236 1237 1238 1239
		/* Only QPSK is supported for DVB-S */
		if (c->modulation != QPSK) {
			dprintk("%s: unsupported modulation selected (%d)\n",
				__func__, c->modulation);
			return -EOPNOTSUPP;
		}
1240

1241 1242
		/* Pilot doesn't exist in DVB-S, turn bit off */
		state->dnxt.pilot_val = CX24116_PILOT_OFF;
1243

1244 1245 1246 1247 1248 1249 1250 1251
		/* DVB-S only supports 0.35 */
		if (c->rolloff != ROLLOFF_35) {
			dprintk("%s: unsupported rolloff selected (%d)\n",
				__func__, c->rolloff);
			return -EOPNOTSUPP;
		}
		state->dnxt.rolloff_val = CX24116_ROLLOFF_035;
		break;
1252

1253 1254
	case SYS_DVBS2:
		dprintk("%s: DVB-S2 delivery system selected\n", __func__);
1255

1256 1257 1258 1259 1260 1261 1262 1263 1264
		/*
		 * NBC 8PSK/QPSK with DVB-S is supported for DVB-S2,
		 * but not hardware auto detection
		 */
		if (c->modulation != PSK_8 && c->modulation != QPSK) {
			dprintk("%s: unsupported modulation selected (%d)\n",
				__func__, c->modulation);
			return -EOPNOTSUPP;
		}
1265

1266 1267
		switch (c->pilot) {
		case PILOT_AUTO:	/* Not supported but emulated */
1268 1269
			state->dnxt.pilot_val = (c->modulation == QPSK)
				? CX24116_PILOT_OFF : CX24116_PILOT_ON;
1270
			retune++;
1271
			break;
1272 1273 1274 1275 1276
		case PILOT_OFF:
			state->dnxt.pilot_val = CX24116_PILOT_OFF;
			break;
		case PILOT_ON:
			state->dnxt.pilot_val = CX24116_PILOT_ON;
1277
			break;
1278 1279 1280 1281 1282
		default:
			dprintk("%s: unsupported pilot mode selected (%d)\n",
				__func__, c->pilot);
			return -EOPNOTSUPP;
		}
1283

1284 1285 1286 1287 1288 1289 1290 1291 1292 1293 1294
		switch (c->rolloff) {
		case ROLLOFF_20:
			state->dnxt.rolloff_val = CX24116_ROLLOFF_020;
			break;
		case ROLLOFF_25:
			state->dnxt.rolloff_val = CX24116_ROLLOFF_025;
			break;
		case ROLLOFF_35:
			state->dnxt.rolloff_val = CX24116_ROLLOFF_035;
			break;
		case ROLLOFF_AUTO:	/* Rolloff must be explicit */
1295
		default:
1296 1297
			dprintk("%s: unsupported rolloff selected (%d)\n",
				__func__, c->rolloff);
1298
			return -EOPNOTSUPP;
1299 1300 1301 1302 1303 1304 1305
		}
		break;

	default:
		dprintk("%s: unsupported delivery system selected (%d)\n",
			__func__, c->delivery_system);
		return -EOPNOTSUPP;
1306
	}
1307
	state->dnxt.delsys = c->delivery_system;
1308 1309 1310 1311
	state->dnxt.modulation = c->modulation;
	state->dnxt.frequency = c->frequency;
	state->dnxt.pilot = c->pilot;
	state->dnxt.rolloff = c->rolloff;
1312

1313 1314
	ret = cx24116_set_inversion(state, c->inversion);
	if (ret !=  0)
1315 1316
		return ret;

1317
	/* FEC_NONE/AUTO for DVB-S2 is not supported and detected here */
1318
	ret = cx24116_set_fec(state, c->delivery_system, c->modulation, c->fec_inner);
1319
	if (ret !=  0)
1320 1321
		return ret;

1322 1323
	ret = cx24116_set_symbolrate(state, c->symbol_rate);
	if (ret !=  0)
1324 1325 1326 1327 1328
		return ret;

	/* discard the 'current' tuning parameters and prepare to tune */
	cx24116_clone_params(fe);

1329
	dprintk("%s:   delsys      = %d\n", __func__, state->dcur.delsys);
1330
	dprintk("%s:   modulation  = %d\n", __func__, state->dcur.modulation);
1331
	dprintk("%s:   frequency   = %d\n", __func__, state->dcur.frequency);
1332 1333 1334 1335 1336
	dprintk("%s:   pilot       = %d (val = 0x%02x)\n", __func__,
		state->dcur.pilot, state->dcur.pilot_val);
	dprintk("%s:   retune      = %d\n", __func__, retune);
	dprintk("%s:   rolloff     = %d (val = 0x%02x)\n", __func__,
		state->dcur.rolloff, state->dcur.rolloff_val);
1337 1338 1339 1340 1341 1342
	dprintk("%s:   symbol_rate = %d\n", __func__, state->dcur.symbol_rate);
	dprintk("%s:   FEC         = %d (mask/val = 0x%02x/0x%02x)\n", __func__,
		state->dcur.fec, state->dcur.fec_mask, state->dcur.fec_val);
	dprintk("%s:   Inversion   = %d (val = 0x%02x)\n", __func__,
		state->dcur.inversion, state->dcur.inversion_val);

1343
	/* This is also done in advise/acquire on HVR4000 but not on LITE */
1344 1345 1346
	if (state->config->set_ts_params)
		state->config->set_ts_params(fe, 0);

1347 1348 1349
	/* Set/Reset B/W */
	cmd.args[0x00] = CMD_BANDWIDTH;
	cmd.args[0x01] = 0x01;
1350
	cmd.len = 0x02;
1351 1352 1353
	ret = cx24116_cmd_execute(fe, &cmd);
	if (ret != 0)
		return ret;
1354

1355 1356 1357 1358 1359 1360 1361 1362 1363 1364 1365 1366 1367 1368 1369
	/* Prepare a tune request */
	cmd.args[0x00] = CMD_TUNEREQUEST;

	/* Frequency */
	cmd.args[0x01] = (state->dcur.frequency & 0xff0000) >> 16;
	cmd.args[0x02] = (state->dcur.frequency & 0x00ff00) >> 8;
	cmd.args[0x03] = (state->dcur.frequency & 0x0000ff);

	/* Symbol Rate */
	cmd.args[0x04] = ((state->dcur.symbol_rate / 1000) & 0xff00) >> 8;
	cmd.args[0x05] = ((state->dcur.symbol_rate / 1000) & 0x00ff);

	/* Automatic Inversion */
	cmd.args[0x06] = state->dcur.inversion_val;

1370 1371
	/* Modulation / FEC / Pilot */
	cmd.args[0x07] = state->dcur.fec_val | state->dcur.pilot_val;
1372 1373 1374 1375 1376

	cmd.args[0x08] = CX24116_SEARCH_RANGE_KHZ >> 8;
	cmd.args[0x09] = CX24116_SEARCH_RANGE_KHZ & 0xff;
	cmd.args[0x0a] = 0x00;
	cmd.args[0x0b] = 0x00;
1377
	cmd.args[0x0c] = state->dcur.rolloff_val;
1378
	cmd.args[0x0d] = state->dcur.fec_mask;
1379

1380
	if (state->dcur.symbol_rate > 30000000) {
1381 1382 1383 1384 1385
		cmd.args[0x0e] = 0x04;
		cmd.args[0x0f] = 0x00;
		cmd.args[0x10] = 0x01;
		cmd.args[0x11] = 0x77;
		cmd.args[0x12] = 0x36;
1386 1387
		cx24116_writereg(state, CX24116_REG_CLKDIV, 0x44);
		cx24116_writereg(state, CX24116_REG_RATEDIV, 0x01);
1388 1389 1390 1391 1392 1393
	} else {
		cmd.args[0x0e] = 0x06;
		cmd.args[0x0f] = 0x00;
		cmd.args[0x10] = 0x00;
		cmd.args[0x11] = 0xFA;
		cmd.args[0x12] = 0x24;
1394 1395
		cx24116_writereg(state, CX24116_REG_CLKDIV, 0x46);
		cx24116_writereg(state, CX24116_REG_RATEDIV, 0x00);
1396 1397
	}

1398
	cmd.len = 0x13;
1399 1400 1401 1402 1403 1404

	/* We need to support pilot and non-pilot tuning in the
	 * driver automatically. This is a workaround for because
	 * the demod does not support autodetect.
	 */
	do {
1405
		/* Reset status register */
1406 1407
		status = cx24116_readreg(state, CX24116_REG_SSTATUS)
			& CX24116_SIGNAL_MASK;
1408
		cx24116_writereg(state, CX24116_REG_SSTATUS, status);
1409 1410 1411

		/* Tune */
		ret = cx24116_cmd_execute(fe, &cmd);
1412
		if (ret != 0)
1413 1414
			break;

1415 1416 1417 1418 1419 1420
		/*
		 * Wait for up to 500 ms before retrying
		 *
		 * If we are able to tune then generally it occurs within 100ms.
		 * If it takes longer, try a different toneburst setting.
		 */
1421
		for (i = 0; i < 50 ; i++) {
1422 1423
			cx24116_read_status(fe, &tunerstat);
			status = tunerstat & (FE_HAS_SIGNAL | FE_HAS_SYNC);
1424 1425
			if (status == (FE_HAS_SIGNAL | FE_HAS_SYNC)) {
				dprintk("%s: Tuned\n", __func__);
1426 1427 1428
				goto tuned;
			}
			msleep(10);
1429
		}
1430

1431
		dprintk("%s: Not tuned\n", __func__);
1432 1433

		/* Toggle pilot bit when in auto-pilot */
1434
		if (state->dcur.pilot == PILOT_AUTO)
1435
			cmd.args[0x07] ^= CX24116_PILOT_ON;
1436
	} while (--retune);
1437

1438 1439 1440
tuned:  /* Set/Reset B/W */
	cmd.args[0x00] = CMD_BANDWIDTH;
	cmd.args[0x01] = 0x00;
1441
	cmd.len = 0x02;
1442 1443 1444 1445
	ret = cx24116_cmd_execute(fe, &cmd);
	if (ret != 0)
		return ret;

1446 1447 1448
	return ret;
}

1449 1450 1451 1452 1453 1454 1455 1456 1457 1458 1459 1460 1461 1462 1463 1464 1465
static int cx24116_tune(struct dvb_frontend *fe, struct dvb_frontend_parameters *params,
	unsigned int mode_flags, unsigned int *delay, fe_status_t *status)
{
	*delay = HZ / 5;
	if (params) {
		int ret = cx24116_set_frontend(fe, params);
		if (ret)
			return ret;
	}
	return cx24116_read_status(fe, status);
}

static int cx24116_get_algo(struct dvb_frontend *fe)
{
	return DVBFE_ALGO_HW;
}

1466 1467 1468 1469 1470 1471 1472 1473 1474 1475 1476 1477 1478 1479 1480
static struct dvb_frontend_ops cx24116_ops = {

	.info = {
		.name = "Conexant CX24116/CX24118",
		.type = FE_QPSK,
		.frequency_min = 950000,
		.frequency_max = 2150000,
		.frequency_stepsize = 1011, /* kHz for QPSK frontends */
		.frequency_tolerance = 5000,
		.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 |
			FE_CAN_FEC_4_5 | FE_CAN_FEC_5_6 | FE_CAN_FEC_6_7 |
			FE_CAN_FEC_7_8 | FE_CAN_FEC_AUTO |
1481
			FE_CAN_2G_MODULATION |
1482 1483 1484 1485 1486 1487
			FE_CAN_QPSK | FE_CAN_RECOVER
	},

	.release = cx24116_release,

	.init = cx24116_initfe,
1488
	.sleep = cx24116_sleep,
1489 1490 1491 1492 1493 1494 1495 1496 1497
	.read_status = cx24116_read_status,
	.read_ber = cx24116_read_ber,
	.read_signal_strength = cx24116_read_signal_strength,
	.read_snr = cx24116_read_snr,
	.read_ucblocks = cx24116_read_ucblocks,
	.set_tone = cx24116_set_tone,
	.set_voltage = cx24116_set_voltage,
	.diseqc_send_master_cmd = cx24116_send_diseqc_msg,
	.diseqc_send_burst = cx24116_diseqc_send_burst,
1498 1499
	.get_frontend_algo = cx24116_get_algo,
	.tune = cx24116_tune,
1500 1501

	.set_property = cx24116_set_property,
1502
	.get_property = cx24116_get_property,
1503 1504 1505 1506 1507 1508 1509
	.set_frontend = cx24116_set_frontend,
};

MODULE_DESCRIPTION("DVB Frontend module for Conexant cx24116/cx24118 hardware");
MODULE_AUTHOR("Steven Toth");
MODULE_LICENSE("GPL");