cx24116.c 38.5 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 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43

    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"

44 45 46 47
static int debug;
module_param(debug, int, 0644);
MODULE_PARM_DESC(debug, "Activates frontend debugging (default:0)");

48 49
#define dprintk(args...) \
	do { \
50 51
		if (debug) \
			printk("cx24116: " args); \
52 53
	} while (0)

54 55 56
#define CX24116_DEFAULT_FIRMWARE "dvb-fe-cx24116.fw"
#define CX24116_SEARCH_RANGE_KHZ 5000

57 58 59 60 61 62 63
/* 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 */
64
#define CX24116_REG_QUALITY8 (0xa3)
65
#define CX24116_REG_QSTATUS (0xbc)
66
#define CX24116_REG_QUALITY0 (0xd5)
67 68 69 70 71 72 73 74
#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)
75 76 77 78 79 80 81
#define CX24116_REG_FECSTATUS (0x9c)    /* configured fec (not tuned) or actual FEC (tuned) 1=1/2 2=2/3 etc */

/* FECSTATUS bits */
#define CX24116_FEC_FECMASK   (0x1f)    /* mask to determine configured fec (not tuned) or actual fec (tuned) */
#define CX24116_FEC_DVBS      (0x20)    /* Select DVB-S demodulator, else DVB-S2 */
#define CX24116_FEC_UNKNOWN   (0x40)    /* Unknown/unused */
#define CX24116_FEC_PILOT     (0x80)    /* Pilot mode requested when tuning else always reset when tuned */
82 83 84 85

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

86 87 88 89 90 91
/* rolloff */
#define CX24116_ROLLOFF_020 (0x00)
#define CX24116_ROLLOFF_025 (0x01)
#define CX24116_ROLLOFF_035 (0x02)

/* pilot bit */
92 93
#define CX24116_PILOT_OFF (0x00)
#define CX24116_PILOT_ON (0x40)
94 95 96 97 98 99 100 101 102 103 104 105 106 107 108

/* 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)
#define CX24116_STATUS_MASK  (0x3f)
#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       */

109 110 111 112 113 114 115 116 117 118 119 120
/* 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)

121 122
/* DiSEqC tone burst */
static int toneburst = 1;
123 124
module_param(toneburst, int, 0644);
MODULE_PARM_DESC(toneburst, "DiSEqC toneburst 0=OFF, 1=TONE CACHE, 2=MESSAGE CACHE (default:1)");
125

126
/* SNR measurements */
127 128 129
static int esno_snr;
module_param(esno_snr, int, 0644);
MODULE_PARM_DESC(debug, "SNR return units, 0=PERCENTAGE 0-100, 1=ESNO(db * 10) (default:0)");
130

131
enum cmds {
132
	CMD_SET_VCO     = 0x10,
133
	CMD_TUNEREQUEST = 0x11,
134 135 136 137 138 139
	CMD_MPEGCONFIG  = 0x13,
	CMD_TUNERINIT   = 0x14,
	CMD_BANDWIDTH   = 0x15,
	CMD_GETAGC      = 0x19,
	CMD_LNBCONFIG   = 0x20,
	CMD_LNBSEND     = 0x21, /* Formerly CMD_SEND_DISEQC */
140 141
	CMD_SET_TONEPRE = 0x22,
	CMD_SET_TONE    = 0x23,
142 143 144
	CMD_UPDFWVERS   = 0x35,
	CMD_TUNERSLEEP  = 0x36,
	CMD_AGCCONTROL  = 0x3b, /* Unknown */
145 146 147
};

/* The Demod/Tuner can't easily provide these, we cache them */
148
struct cx24116_tuning {
149 150 151 152 153 154
	u32 frequency;
	u32 symbol_rate;
	fe_spectral_inversion_t inversion;
	fe_code_rate_t fec;

	fe_modulation_t modulation;
155 156
	fe_pilot_t pilot;
	fe_rolloff_t rolloff;
157 158 159 160 161

	/* Demod values */
	u8 fec_val;
	u8 fec_mask;
	u8 inversion_val;
162
	u8 pilot_val;
163
	u8 rolloff_val;
164 165 166
};

/* Basic commands that are sent to the firmware */
167
struct cx24116_cmd {
168 169 170 171
	u8 len;
	u8 args[CX24116_ARGLEN];
};

172 173 174
struct cx24116_state {
	struct i2c_adapter *i2c;
	const struct cx24116_config *config;
175 176 177 178 179 180 181 182

	struct dvb_frontend frontend;

	struct cx24116_tuning dcur;
	struct cx24116_tuning dnxt;

	u8 skip_fw_load;
	u8 burst;
183
	struct cx24116_cmd dsec_cmd;
184 185
};

186
static int cx24116_writereg(struct cx24116_state *state, int reg, int data)
187 188 189 190 191 192
{
	u8 buf[] = { reg, data };
	struct i2c_msg msg = { .addr = state->config->demod_address,
		.flags = 0, .buf = buf, .len = 2 };
	int err;

193
	if (debug > 1)
194
		printk("cx24116: %s: write reg 0x%02x, value 0x%02x\n",
195
			__func__, reg, data);
196

197 198
	err = i2c_transfer(state->i2c, &msg, 1);
	if (err != 1) {
199 200 201 202 203 204 205 206 207
		printk("%s: writereg error(err == %i, reg == 0x%02x,"
			 " value == 0x%02x)\n", __func__, err, reg, data);
		return -EREMOTEIO;
	}

	return 0;
}

/* Bulk byte writes to a single I2C address, for 32k firmware load */
208 209
static int cx24116_writeregN(struct cx24116_state *state, int reg,
	u8 *data, u16 len)
210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229
{
	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;

230
	if (debug > 1)
231
		printk("cx24116: %s:  write regN 0x%02x, len = %d\n",
232
			__func__, reg, len);
233

234 235
	ret = i2c_transfer(state->i2c, &msg, 1);
	if (ret != 1) {
236 237 238 239 240 241 242 243 244 245 246
		printk("%s: writereg error(err == %i, reg == 0x%02x\n",
			 __func__, ret, reg);
		ret = -EREMOTEIO;
	}

error:
	kfree(buf);

	return ret;
}

247
static int cx24116_readreg(struct cx24116_state *state, u8 reg)
248 249 250 251 252
{
	int ret;
	u8 b0[] = { reg };
	u8 b1[] = { 0 };
	struct i2c_msg msg[] = {
253 254 255 256
		{ .addr = state->config->demod_address, .flags = 0,
			.buf = b0, .len = 1 },
		{ .addr = state->config->demod_address, .flags = I2C_M_RD,
			.buf = b1, .len = 1 }
257 258 259 260 261 262 263 264 265
	};

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

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

266 267 268
	if (debug > 1)
		printk("cx24116: read reg 0x%02x, value 0x%02x\n",
			reg, b1[0]);
269 270 271 272

	return b1[0];
}

273
static int cx24116_set_inversion(struct cx24116_state *state, fe_spectral_inversion_t inversion)
274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295
{
	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;
}

296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 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 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355
/*
 * 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
 * status 1f | signal c3c0 | snr a333 | ber 00000098 | unc 00000000 | FE_HAS_LOCK
 *
 * mask/val = 0x04, 0x30
 * status 1f | signal c3c0 | snr a333 | ber 00000000 | unc 00000000 | FE_HAS_LOCK
 *
 * 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.
 */

356 357 358 359 360
/* 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.
 */
struct cx24116_modfec {
361
	fe_delivery_system_t delivery_system;
362 363 364 365 366 367
	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 */
368 369

 /*mod   fec       mask  val */
370 371 372 373 374 375 376 377 378 379
 { 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 },
380
 /* NBC-QPSK */
381 382 383 384 385 386 387 388
 { 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 },
389
 /* 8PSK */
390 391 392 393 394 395
 { 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 },
396 397 398 399
 /*
  * `val' can be found in the FECSTATUS register when tuning.
  * FECSTATUS will give the actual FEC in use if tuning was successful.
  */
400 401
};

402
static int cx24116_lookup_fecmod(struct cx24116_state *state,
403 404 405 406
	fe_modulation_t m, fe_code_rate_t f)
{
	int i, ret = -EOPNOTSUPP;

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

409 410 411
	for (i = 0; i < ARRAY_SIZE(CX24116_MODFEC_MODES); i++) {
		if ((m == CX24116_MODFEC_MODES[i].modulation) &&
			(f == CX24116_MODFEC_MODES[i].fec)) {
412 413 414 415 416 417 418 419
				ret = i;
				break;
			}
	}

	return ret;
}

420
static int cx24116_set_fec(struct cx24116_state *state, fe_modulation_t mod, fe_code_rate_t fec)
421 422
{
	int ret = 0;
423 424

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

	ret = cx24116_lookup_fecmod(state, mod, fec);

428
	if (ret < 0)
429 430
		return ret;

431
	state->dnxt.fec = fec;
432 433
	state->dnxt.fec_val = CX24116_MODFEC_MODES[ret].val;
	state->dnxt.fec_mask = CX24116_MODFEC_MODES[ret].mask;
434 435
	dprintk("%s() mask/val = 0x%02x/0x%02x\n", __func__,
		state->dnxt.fec_mask, state->dnxt.fec_val);
436 437 438 439

	return 0;
}

440
static int cx24116_set_symbolrate(struct cx24116_state *state, u32 rate)
441
{
442
	dprintk("%s(%d)\n", __func__, rate);
443

444 445 446 447 448 449
	/*  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;
	}
450 451

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

454
	return 0;
455 456
}

457 458
static int cx24116_load_firmware(struct dvb_frontend *fe,
	const struct firmware *fw);
459

460
static int cx24116_firmware_ondemand(struct dvb_frontend *fe)
461 462 463 464 465
{
	struct cx24116_state *state = fe->demodulator_priv;
	const struct firmware *fw;
	int ret = 0;

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

468
	if (cx24116_readreg(state, 0x20) > 0) {
469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501

		if (state->skip_fw_load)
			return 0;

		/* Load firmware */
		/* request the firmware, this will block until someone uploads it */
		printk("%s: Waiting for firmware upload (%s)...\n", __func__, CX24116_DEFAULT_FIRMWARE);
		ret = request_firmware(&fw, CX24116_DEFAULT_FIRMWARE, &state->i2c->dev);
		printk("%s: Waiting for firmware upload(2)...\n", __func__);
		if (ret) {
			printk("%s: No firmware uploaded (timeout or file not found?)\n", __func__);
			return ret;
		}

		/* Make sure we don't recurse back through here during loading */
		state->skip_fw_load = 1;

		ret = cx24116_load_firmware(fe, fw);
		if (ret)
			printk("%s: Writing firmware to device failed\n", __func__);

		release_firmware(fw);

		printk("%s: Firmware upload %s\n", __func__, ret == 0 ? "complete" : "failed");

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

	return ret;
}

/* Take a basic firmware command structure, format it and forward it for processing */
502
static int cx24116_cmd_execute(struct dvb_frontend *fe, struct cx24116_cmd *cmd)
503 504 505 506 507 508 509
{
	struct cx24116_state *state = fe->demodulator_priv;
	int i, ret;

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

	/* Load the firmware if required */
510 511
	ret = cx24116_firmware_ondemand(fe);
	if (ret != 0) {
512 513 514 515 516
		printk("%s(): Unable initialise the firmware\n", __func__);
		return ret;
	}

	/* Write the command */
517
	for (i = 0; i < cmd->len ; i++) {
518 519 520 521 522
		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 */
523
	cx24116_writereg(state, CX24116_REG_EXECUTE, 0x01);
524
	while (cx24116_readreg(state, CX24116_REG_EXECUTE)) {
525
		msleep(10);
526
		if (i++ > 64) {
527 528 529 530 531 532 533 534
			/* Avoid looping forever if the firmware does no respond */
			printk("%s() Firmware not responding\n", __func__);
			return -EREMOTEIO;
		}
	}
	return 0;
}

535 536
static int cx24116_load_firmware(struct dvb_frontend *fe,
	const struct firmware *fw)
537
{
538
	struct cx24116_state *state = fe->demodulator_priv;
539
	struct cx24116_cmd cmd;
540 541
	int i, ret;
	unsigned char vers[4];
542 543

	dprintk("%s\n", __func__);
544 545 546 547 548 549
	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]);
550 551 552 553 554 555 556

	/* 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 */
557 558 559

	/* Init PLL */
	cx24116_writereg(state, 0xE5, 0x00);
560
	cx24116_writereg(state, 0xF1, 0x08);
561 562 563 564 565 566 567 568 569
	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);
570

571
	/* Unknown */
572 573 574 575 576 577 578 579 580 581 582 583
	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);

584 585
	/* Firmware CMD 10: VCO config */
	cmd.args[0x00] = CMD_SET_VCO;
586 587 588 589 590 591 592 593 594
	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;
595
	cmd.len = 0x0a;
596 597 598 599
	ret = cx24116_cmd_execute(fe, &cmd);
	if (ret != 0)
		return ret;

600
	cx24116_writereg(state, CX24116_REG_SSTATUS, 0x00);
601

602 603
	/* Firmware CMD 14: Tuner config */
	cmd.args[0x00] = CMD_TUNERINIT;
604 605
	cmd.args[0x01] = 0x00;
	cmd.args[0x02] = 0x00;
606
	cmd.len = 0x03;
607 608 609 610 611 612
	ret = cx24116_cmd_execute(fe, &cmd);
	if (ret != 0)
		return ret;

	cx24116_writereg(state, 0xe5, 0x00);

613 614
	/* Firmware CMD 13: MPEG config */
	cmd.args[0x00] = CMD_MPEGCONFIG;
615 616 617
	cmd.args[0x01] = 0x01;
	cmd.args[0x02] = 0x75;
	cmd.args[0x03] = 0x00;
618 619 620 621
	if (state->config->mpg_clk_pos_pol)
		cmd.args[0x04] = state->config->mpg_clk_pos_pol;
	else
		cmd.args[0x04] = 0x02;
622
	cmd.args[0x05] = 0x00;
623
	cmd.len = 0x06;
624 625 626 627
	ret = cx24116_cmd_execute(fe, &cmd);
	if (ret != 0)
		return ret;

628 629
	/* Firmware CMD 35: Get firmware version */
	cmd.args[0x00] = CMD_UPDFWVERS;
630 631
	cmd.len = 0x02;
	for (i = 0; i < 4; i++) {
632 633 634 635
		cmd.args[0x01] = i;
		ret = cx24116_cmd_execute(fe, &cmd);
		if (ret != 0)
			return ret;
636
		vers[i] = cx24116_readreg(state, CX24116_REG_MAILBOX);
637 638 639 640
	}
	printk("%s: FW version %i.%i.%i.%i\n", __func__,
		vers[0], vers[1], vers[2], vers[3]);

641 642 643
	return 0;
}

644 645
static int cx24116_set_voltage(struct dvb_frontend *fe,
	fe_sec_voltage_t voltage)
646 647
{
	/* The isl6421 module will override this function in the fops. */
648 649
	dprintk("%s() This should never appear if the isl6421 module "
		"is loaded correctly\n", __func__);
650 651 652 653

	return -EOPNOTSUPP;
}

654
static int cx24116_read_status(struct dvb_frontend *fe, fe_status_t *status)
655 656 657
{
	struct cx24116_state *state = fe->demodulator_priv;

658
	int lock = cx24116_readreg(state, CX24116_REG_SSTATUS);
659 660 661 662 663

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

	*status = 0;

664
	if (lock & CX24116_HAS_SIGNAL)
665
		*status |= FE_HAS_SIGNAL;
666
	if (lock & CX24116_HAS_CARRIER)
667
		*status |= FE_HAS_CARRIER;
668
	if (lock & CX24116_HAS_VITERBI)
669
		*status |= FE_HAS_VITERBI;
670
	if (lock & CX24116_HAS_SYNCLOCK)
671 672 673 674 675
		*status |= FE_HAS_SYNC | FE_HAS_LOCK;

	return 0;
}

676
static int cx24116_read_ber(struct dvb_frontend *fe, u32 *ber)
677
{
678 679
	struct cx24116_state *state = fe->demodulator_priv;

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

682 683 684 685
	*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);
686 687 688 689

	return 0;
}

690
/* TODO Determine function and scale appropriately */
691 692
static int cx24116_read_signal_strength(struct dvb_frontend *fe,
	u16 *signal_strength)
693 694
{
	struct cx24116_state *state = fe->demodulator_priv;
695 696 697
	struct cx24116_cmd cmd;
	int ret;
	u16 sig_reading;
698 699 700

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

701 702
	/* Firmware CMD 19: Get AGC */
	cmd.args[0x00] = CMD_GETAGC;
703
	cmd.len = 0x01;
704 705 706
	ret = cx24116_cmd_execute(fe, &cmd);
	if (ret != 0)
		return ret;
707

708 709 710 711 712
	sig_reading =
		(cx24116_readreg(state,
			CX24116_REG_SSTATUS) & CX24116_SIGNAL_MASK) |
		(cx24116_readreg(state, CX24116_REG_SIGNAL) << 6);
	*signal_strength = 0 - sig_reading;
713

714 715
	dprintk("%s: raw / cooked = 0x%04x / 0x%04x\n",
		__func__, sig_reading, *signal_strength);
716 717 718 719

	return 0;
}

720
/* SNR (0..100)% = (sig & 0xf0) * 10 + (sig & 0x0f) * 10 / 16 */
721
static int cx24116_read_snr_pct(struct dvb_frontend *fe, u16 *snr)
722
{
723 724 725
	struct cx24116_state *state = fe->demodulator_priv;
	u8 snr_reading;
	static const u32 snr_tab[] = { /* 10 x Table (rounded up) */
726 727 728 729
		0x00000, 0x0199A, 0x03333, 0x04ccD, 0x06667,
		0x08000, 0x0999A, 0x0b333, 0x0cccD, 0x0e667,
		0x10000, 0x1199A, 0x13333, 0x14ccD, 0x16667,
		0x18000 };
730

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

733
	snr_reading = cx24116_readreg(state, CX24116_REG_QUALITY0);
734

735
	if (snr_reading >= 0xa0 /* 100% */)
736 737
		*snr = 0xffff;
	else
738 739
		*snr = snr_tab[(snr_reading & 0xf0) >> 4] +
			(snr_tab[(snr_reading & 0x0f)] >> 4);
740 741 742

	dprintk("%s: raw / cooked = 0x%02x / 0x%04x\n", __func__,
		snr_reading, *snr);
743 744 745 746

	return 0;
}

747 748 749 750
/* The reelbox patches show the value in the registers represents
 * ESNO, from 0->30db (values 0->300). We provide this value by
 * default.
 */
751
static int cx24116_read_snr_esno(struct dvb_frontend *fe, u16 *snr)
752 753 754 755 756 757 758 759 760 761 762 763 764
{
	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;
}

765
static int cx24116_read_snr(struct dvb_frontend *fe, u16 *snr)
766 767 768 769 770 771 772
{
	if (esno_snr == 1)
		return cx24116_read_snr_esno(fe, snr);
	else
		return cx24116_read_snr_pct(fe, snr);
}

773
static int cx24116_read_ucblocks(struct dvb_frontend *fe, u32 *ucblocks)
774
{
775 776
	struct cx24116_state *state = fe->demodulator_priv;

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

779
	*ucblocks = (cx24116_readreg(state, CX24116_REG_UCB8) << 8) |
780
		cx24116_readreg(state, CX24116_REG_UCB0);
781 782 783 784 785

	return 0;
}

/* Overwrite the current tuning params, we are about to tune */
786
static void cx24116_clone_params(struct dvb_frontend *fe)
787 788 789 790 791
{
	struct cx24116_state *state = fe->demodulator_priv;
	memcpy(&state->dcur, &state->dnxt, sizeof(state->dcur));
}

792
/* Wait for LNB */
793
static int cx24116_wait_for_lnb(struct dvb_frontend *fe)
794 795 796 797 798 799 800 801
{
	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 */
802
	for (i = 0; i < 30 ; i++) {
803 804 805 806 807 808 809 810 811 812
		if (cx24116_readreg(state, CX24116_REG_QSTATUS) & 0x20)
			return 0;
		msleep(10);
	}

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

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

813 814
static int cx24116_set_tone(struct dvb_frontend *fe,
	fe_sec_tone_mode_t tone)
815 816 817 818 819
{
	struct cx24116_cmd cmd;
	int ret;

	dprintk("%s(%d)\n", __func__, tone);
820
	if ((tone != SEC_TONE_ON) && (tone != SEC_TONE_OFF)) {
821 822 823 824
		printk("%s: Invalid, tone=%d\n", __func__, tone);
		return -EINVAL;
	}

825 826
	/* Wait for LNB ready */
	ret = cx24116_wait_for_lnb(fe);
827
	if (ret != 0)
828 829 830 831 832
		return ret;

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

833 834 835
	/* This is always done before the tone is set */
	cmd.args[0x00] = CMD_SET_TONEPRE;
	cmd.args[0x01] = 0x00;
836
	cmd.len = 0x02;
837 838 839 840 841 842 843 844 845 846 847 848 849 850 851
	ret = cx24116_cmd_execute(fe, &cmd);
	if (ret != 0)
		return ret;

	/* 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:
852
		dprintk("%s: setting tone off\n", __func__);
853 854 855
		cmd.args[0x03] = 0x00;
		break;
	}
856
	cmd.len = 0x04;
857

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

861 862 863 864
	return cx24116_cmd_execute(fe, &cmd);
}

/* Initialise DiSEqC */
865
static int cx24116_diseqc_init(struct dvb_frontend *fe)
866 867
{
	struct cx24116_state *state = fe->demodulator_priv;
868 869 870 871 872 873 874 875 876 877 878 879
	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;
880
	cmd.len = 0x08;
881 882 883 884 885 886 887 888 889 890 891 892 893 894
	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;
	state->dsec_cmd.args[CX24116_DISEQC_ARG4_0] = 0x00; /* Continuation flag? */
895

896 897 898 899
	/* DiSEqC message length */
	state->dsec_cmd.args[CX24116_DISEQC_MSGLEN] = 0x00;

	/* Command length */
900
	state->dsec_cmd.len = CX24116_DISEQC_MSGOFS;
901 902 903 904 905

	return 0;
}

/* Send DiSEqC message with derived burst (hack) || previous burst */
906 907
static int cx24116_send_diseqc_msg(struct dvb_frontend *fe,
	struct dvb_diseqc_master_cmd *d)
908 909 910 911 912 913 914
{
	struct cx24116_state *state = fe->demodulator_priv;
	int i, ret;

	/* Dump DiSEqC message */
	if (debug) {
		printk("cx24116: %s(", __func__);
915
		for (i = 0 ; i < d->msg_len ;) {
916
			printk("0x%02x", d->msg[i]);
917
			if (++i < d->msg_len)
918
				printk(", ");
919
		}
920
		printk(") toneburst=%d\n", toneburst);
921 922
	}

923
	/* Validate length */
924
	if (d->msg_len > (CX24116_ARGLEN - CX24116_DISEQC_MSGOFS))
925 926 927 928
		return -EINVAL;

	/* DiSEqC message */
	for (i = 0; i < d->msg_len; i++)
929 930 931 932 933 934
		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 */
935 936
	state->dsec_cmd.len = CX24116_DISEQC_MSGOFS +
		state->dsec_cmd.args[CX24116_DISEQC_MSGLEN];
937 938

	/* DiSEqC toneburst */
939
	if (toneburst == CX24116_DISEQC_MESGCACHE)
940 941 942
		/* Message is cached */
		return 0;

943
	else if (toneburst == CX24116_DISEQC_TONEOFF)
944 945 946
		/* Message is sent without burst */
		state->dsec_cmd.args[CX24116_DISEQC_BURST] = 0;

947
	else if (toneburst == CX24116_DISEQC_TONECACHE) {
948 949 950 951 952 953 954 955 956 957
		/*
		 * 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
		 *
958
		 * databyte[3]= 8421:8421
959 960 961 962 963 964 965
		 *              ABCD:WXYZ
		 *              CLR :SET
		 *
		 *              WX= PORT SELECT 0..3    (X=TONEBURST)
		 *              Y = VOLTAGE             (0=13V, 1=18V)
		 *              Z = BAND                (0=LOW, 1=HIGH(22K))
		 */
966 967 968 969 970 971
		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]);
972
	}
973

974 975
	/* Wait for LNB ready */
	ret = cx24116_wait_for_lnb(fe);
976
	if (ret != 0)
977
		return ret;
978

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

982 983
	/* Command */
	ret = cx24116_cmd_execute(fe, &state->dsec_cmd);
984
	if (ret != 0)
985 986 987
		return ret;
	/*
	 * Wait for send
988 989
	 *
	 * Eutelsat spec:
990 991 992 993 994
	 * >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)
995
	 */
996 997
	msleep((state->dsec_cmd.args[CX24116_DISEQC_MSGLEN] << 4) +
		((toneburst == CX24116_DISEQC_TONEOFF) ? 30 : 60));
998

999
	return 0;
1000 1001 1002
}

/* Send DiSEqC burst */
1003 1004
static int cx24116_diseqc_send_burst(struct dvb_frontend *fe,
	fe_sec_mini_cmd_t burst)
1005 1006 1007 1008
{
	struct cx24116_state *state = fe->demodulator_priv;
	int ret;

1009
	dprintk("%s(%d) toneburst=%d\n", __func__, burst, toneburst);
1010

1011
	/* DiSEqC burst */
1012
	if (burst == SEC_MINI_A)
1013 1014 1015 1016 1017
		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;
1018 1019 1020
	else
		return -EINVAL;

1021
	/* DiSEqC toneburst */
1022
	if (toneburst != CX24116_DISEQC_MESGCACHE)
1023 1024
		/* Burst is cached */
		return 0;
1025

1026
	/* Burst is to be sent with cached message */
1027

1028 1029
	/* Wait for LNB ready */
	ret = cx24116_wait_for_lnb(fe);
1030
	if (ret != 0)
1031
		return ret;
1032

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

1036 1037
	/* Command */
	ret = cx24116_cmd_execute(fe, &state->dsec_cmd);
1038
	if (ret != 0)
1039 1040 1041 1042 1043 1044 1045 1046 1047 1048 1049 1050
		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)
	 */
1051
	msleep((state->dsec_cmd.args[CX24116_DISEQC_MSGLEN] << 4) + 60);
1052 1053

	return 0;
1054 1055
}

1056
static void cx24116_release(struct dvb_frontend *fe)
1057
{
1058 1059
	struct cx24116_state *state = fe->demodulator_priv;
	dprintk("%s\n", __func__);
1060 1061 1062 1063 1064
	kfree(state);
}

static struct dvb_frontend_ops cx24116_ops;

1065 1066
struct dvb_frontend *cx24116_attach(const struct cx24116_config *config,
	struct i2c_adapter *i2c)
1067
{
1068
	struct cx24116_state *state = NULL;
1069 1070
	int ret;

1071
	dprintk("%s\n", __func__);
1072 1073 1074 1075 1076

	/* allocate memory for the internal state */
	state = kmalloc(sizeof(struct cx24116_state), GFP_KERNEL);
	if (state == NULL) {
		printk("Unable to kmalloc\n");
1077
		goto error1;
1078 1079 1080 1081 1082 1083 1084 1085 1086 1087 1088 1089
	}

	/* setup the state */
	memset(state, 0, sizeof(struct cx24116_state));

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

	/* check if the demod is present */
	ret = (cx24116_readreg(state, 0xFF) << 8) | cx24116_readreg(state, 0xFE);
	if (ret != 0x0501) {
		printk("Invalid probe, probably not a CX24116 device\n");
1090
		goto error2;
1091 1092 1093 1094 1095 1096 1097
	}

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

1098
error2: kfree(state);
1099
error1: return NULL;
1100
}
1101 1102
EXPORT_SYMBOL(cx24116_attach);

1103 1104 1105 1106 1107
/*
 * Initialise or wake up device
 *
 * Power config will reset and load initial firmware if required
 */
1108
static int cx24116_initfe(struct dvb_frontend *fe)
1109
{
1110
	struct cx24116_state *state = fe->demodulator_priv;
1111 1112
	struct cx24116_cmd cmd;
	int ret;
1113

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

1116 1117 1118 1119
	/* Power on */
	cx24116_writereg(state, 0xe0, 0);
	cx24116_writereg(state, 0xe1, 0);
	cx24116_writereg(state, 0xea, 0);
1120

1121 1122 1123
	/* Firmware CMD 36: Power config */
	cmd.args[0x00] = CMD_TUNERSLEEP;
	cmd.args[0x01] = 0;
1124
	cmd.len = 0x02;
1125
	ret = cx24116_cmd_execute(fe, &cmd);
1126
	if (ret != 0)
1127 1128 1129
		return ret;

	return cx24116_diseqc_init(fe);
1130 1131
}

1132 1133 1134
/*
 * Put device to sleep
 */
1135
static int cx24116_sleep(struct dvb_frontend *fe)
1136
{
1137
	struct cx24116_state *state = fe->demodulator_priv;
1138 1139 1140
	struct cx24116_cmd cmd;
	int ret;

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

1143 1144 1145
	/* Firmware CMD 36: Power config */
	cmd.args[0x00] = CMD_TUNERSLEEP;
	cmd.args[0x01] = 1;
1146
	cmd.len = 0x02;
1147
	ret = cx24116_cmd_execute(fe, &cmd);
1148
	if (ret != 0)
1149 1150 1151 1152 1153 1154 1155 1156
		return ret;

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

	return 0;
1157 1158
}

1159 1160
static int cx24116_set_property(struct dvb_frontend *fe,
	struct dtv_property *tvp)
1161 1162 1163 1164 1165
{
	dprintk("%s(..)\n", __func__);
	return 0;
}

1166 1167
static int cx24116_get_property(struct dvb_frontend *fe,
	struct dtv_property *tvp)
1168
{
1169
	dprintk("%s(..)\n", __func__);
1170 1171 1172 1173 1174 1175
	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.
 */
1176 1177
static int cx24116_set_frontend(struct dvb_frontend *fe,
	struct dvb_frontend_parameters *p)
1178 1179
{
	struct cx24116_state *state = fe->demodulator_priv;
1180
	struct dtv_frontend_properties *c = &fe->dtv_property_cache;
1181 1182
	struct cx24116_cmd cmd;
	fe_status_t tunerstat;
1183
	int i, status, ret, retune;
1184

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

1187 1188 1189
	switch (c->delivery_system) {
	case SYS_DVBS:
		dprintk("%s: DVB-S delivery system selected\n", __func__);
1190

1191 1192 1193 1194 1195 1196
		/* Only QPSK is supported for DVB-S */
		if (c->modulation != QPSK) {
			dprintk("%s: unsupported modulation selected (%d)\n",
				__func__, c->modulation);
			return -EOPNOTSUPP;
		}
1197

1198 1199 1200
		/* Pilot doesn't exist in DVB-S, turn bit off */
		state->dnxt.pilot_val = CX24116_PILOT_OFF;
		retune = 1;
1201

1202 1203 1204 1205 1206 1207 1208 1209
		/* 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;
1210

1211 1212
	case SYS_DVBS2:
		dprintk("%s: DVB-S2 delivery system selected\n", __func__);
1213

1214 1215 1216 1217 1218 1219 1220 1221 1222
		/*
		 * 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;
		}
1223

1224 1225 1226 1227 1228 1229 1230 1231
		switch (c->pilot) {
		case PILOT_AUTO:	/* Not supported but emulated */
			retune = 2;	/* Fall-through */
		case PILOT_OFF:
			state->dnxt.pilot_val = CX24116_PILOT_OFF;
			break;
		case PILOT_ON:
			state->dnxt.pilot_val = CX24116_PILOT_ON;
1232
			break;
1233 1234 1235 1236 1237
		default:
			dprintk("%s: unsupported pilot mode selected (%d)\n",
				__func__, c->pilot);
			return -EOPNOTSUPP;
		}
1238

1239 1240 1241 1242 1243 1244 1245 1246 1247 1248 1249
		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 */
1250
		default:
1251 1252
			dprintk("%s: unsupported rolloff selected (%d)\n",
				__func__, c->rolloff);
1253
			return -EOPNOTSUPP;
1254 1255 1256 1257 1258 1259 1260
		}
		break;

	default:
		dprintk("%s: unsupported delivery system selected (%d)\n",
			__func__, c->delivery_system);
		return -EOPNOTSUPP;
1261
	}
1262 1263 1264 1265
	state->dnxt.modulation = c->modulation;
	state->dnxt.frequency = c->frequency;
	state->dnxt.pilot = c->pilot;
	state->dnxt.rolloff = c->rolloff;
1266

1267 1268
	ret = cx24116_set_inversion(state, c->inversion);
	if (ret !=  0)
1269 1270
		return ret;

1271
	/* FEC_NONE/AUTO for DVB-S2 is not supported and detected here */
1272 1273
	ret = cx24116_set_fec(state, c->modulation, c->fec_inner);
	if (ret !=  0)
1274 1275
		return ret;

1276 1277
	ret = cx24116_set_symbolrate(state, c->symbol_rate);
	if (ret !=  0)
1278 1279 1280 1281 1282
		return ret;

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

1283
	dprintk("%s:   modulation  = %d\n", __func__, state->dcur.modulation);
1284
	dprintk("%s:   frequency   = %d\n", __func__, state->dcur.frequency);
1285 1286 1287 1288 1289
	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);
1290 1291 1292 1293 1294 1295
	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);

1296
	/* This is also done in advise/acquire on HVR4000 but not on LITE */
1297 1298 1299
	if (state->config->set_ts_params)
		state->config->set_ts_params(fe, 0);

1300 1301 1302
	/* Set/Reset B/W */
	cmd.args[0x00] = CMD_BANDWIDTH;
	cmd.args[0x01] = 0x01;
1303
	cmd.len = 0x02;
1304 1305 1306
	ret = cx24116_cmd_execute(fe, &cmd);
	if (ret != 0)
		return ret;
1307

1308 1309 1310 1311 1312 1313 1314 1315 1316 1317 1318 1319 1320 1321 1322
	/* 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;

1323 1324
	/* Modulation / FEC / Pilot */
	cmd.args[0x07] = state->dcur.fec_val | state->dcur.pilot_val;
1325 1326 1327 1328 1329

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

1333
	if (state->dcur.symbol_rate > 30000000) {
1334 1335 1336 1337 1338
		cmd.args[0x0e] = 0x04;
		cmd.args[0x0f] = 0x00;
		cmd.args[0x10] = 0x01;
		cmd.args[0x11] = 0x77;
		cmd.args[0x12] = 0x36;
1339 1340
		cx24116_writereg(state, CX24116_REG_CLKDIV, 0x44);
		cx24116_writereg(state, CX24116_REG_RATEDIV, 0x01);
1341 1342 1343 1344 1345 1346
	} else {
		cmd.args[0x0e] = 0x06;
		cmd.args[0x0f] = 0x00;
		cmd.args[0x10] = 0x00;
		cmd.args[0x11] = 0xFA;
		cmd.args[0x12] = 0x24;
1347 1348
		cx24116_writereg(state, CX24116_REG_CLKDIV, 0x46);
		cx24116_writereg(state, CX24116_REG_RATEDIV, 0x00);
1349 1350
	}

1351
	cmd.len = 0x13;
1352 1353 1354 1355 1356 1357

	/* 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 {
1358
		/* Reset status register */
1359 1360
		status = cx24116_readreg(state, CX24116_REG_SSTATUS)
			& CX24116_SIGNAL_MASK;
1361
		cx24116_writereg(state, CX24116_REG_SSTATUS, status);
1362 1363 1364

		/* Tune */
		ret = cx24116_cmd_execute(fe, &cmd);
1365
		if (ret != 0)
1366 1367
			break;

1368 1369 1370 1371 1372 1373
		/*
		 * 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.
		 */
1374
		for (i = 0; i < 50 ; i++) {
1375 1376
			cx24116_read_status(fe, &tunerstat);
			status = tunerstat & (FE_HAS_SIGNAL | FE_HAS_SYNC);
1377 1378
			if (status == (FE_HAS_SIGNAL | FE_HAS_SYNC)) {
				dprintk("%s: Tuned\n", __func__);
1379 1380 1381
				goto tuned;
			}
			msleep(10);
1382
		}
1383

1384
		dprintk("%s: Not tuned\n", __func__);
1385 1386

		/* Toggle pilot bit when in auto-pilot */
1387
		if (state->dcur.pilot == PILOT_AUTO)
1388
			cmd.args[0x07] ^= CX24116_PILOT_ON;
1389
	} while (--retune);
1390

1391 1392 1393
tuned:  /* Set/Reset B/W */
	cmd.args[0x00] = CMD_BANDWIDTH;
	cmd.args[0x01] = 0x00;
1394
	cmd.len = 0x02;
1395 1396 1397 1398
	ret = cx24116_cmd_execute(fe, &cmd);
	if (ret != 0)
		return ret;

1399 1400 1401 1402 1403 1404 1405 1406 1407 1408 1409 1410 1411 1412 1413 1414 1415 1416 1417 1418 1419 1420 1421 1422
	return ret;
}

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 |
			FE_CAN_QPSK | FE_CAN_RECOVER
	},

	.release = cx24116_release,

	.init = cx24116_initfe,
1423
	.sleep = cx24116_sleep,
1424 1425 1426 1427 1428 1429 1430 1431 1432 1433 1434
	.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,

	.set_property = cx24116_set_property,
1435
	.get_property = cx24116_get_property,
1436 1437 1438 1439 1440 1441 1442
	.set_frontend = cx24116_set_frontend,
};

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