cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

cx24120.c (42454B)


      1// SPDX-License-Identifier: GPL-2.0-or-later
      2/*
      3    Conexant cx24120/cx24118 - DVBS/S2 Satellite demod/tuner driver
      4
      5    Copyright (C) 2008 Patrick Boettcher <pb@linuxtv.org>
      6    Copyright (C) 2009 Sergey Tyurin <forum.free-x.de>
      7    Updated 2012 by Jannis Achstetter <jannis_achstetter@web.de>
      8    Copyright (C) 2015 Jemma Denson <jdenson@gmail.com>
      9	April 2015
     10	    Refactored & simplified driver
     11	    Updated to work with delivery system supplied by DVBv5
     12	    Add frequency, fec & pilot to get_frontend
     13
     14	Cards supported: Technisat Skystar S2
     15
     16*/
     17
     18#include <linux/slab.h>
     19#include <linux/kernel.h>
     20#include <linux/module.h>
     21#include <linux/moduleparam.h>
     22#include <linux/init.h>
     23#include <linux/firmware.h>
     24#include <media/dvb_frontend.h>
     25#include "cx24120.h"
     26
     27#define CX24120_SEARCH_RANGE_KHZ 5000
     28#define CX24120_FIRMWARE "dvb-fe-cx24120-1.20.58.2.fw"
     29
     30/* cx24120 i2c registers  */
     31#define CX24120_REG_CMD_START	0x00		/* write cmd_id */
     32#define CX24120_REG_CMD_ARGS	0x01		/* write command arguments */
     33#define CX24120_REG_CMD_END	0x1f		/* write 0x01 for end */
     34
     35#define CX24120_REG_MAILBOX	0x33
     36#define CX24120_REG_FREQ3	0x34		/* frequency */
     37#define CX24120_REG_FREQ2	0x35
     38#define CX24120_REG_FREQ1	0x36
     39
     40#define CX24120_REG_FECMODE	0x39		/* FEC status */
     41#define CX24120_REG_STATUS	0x3a		/* Tuner status */
     42#define CX24120_REG_SIGSTR_H	0x3a		/* Signal strength high */
     43#define CX24120_REG_SIGSTR_L	0x3b		/* Signal strength low byte */
     44#define CX24120_REG_QUALITY_H	0x40		/* SNR high byte */
     45#define CX24120_REG_QUALITY_L	0x41		/* SNR low byte */
     46
     47#define CX24120_REG_BER_HH	0x47		/* BER high byte of high word */
     48#define CX24120_REG_BER_HL	0x48		/* BER low byte of high word */
     49#define CX24120_REG_BER_LH	0x49		/* BER high byte of low word */
     50#define CX24120_REG_BER_LL	0x4a		/* BER low byte of low word */
     51
     52#define CX24120_REG_UCB_H	0x50		/* UCB high byte */
     53#define CX24120_REG_UCB_L	0x51		/* UCB low byte  */
     54
     55#define CX24120_REG_CLKDIV	0xe6
     56#define CX24120_REG_RATEDIV	0xf0
     57
     58#define CX24120_REG_REVISION	0xff		/* Chip revision (ro) */
     59
     60/* Command messages */
     61enum command_message_id {
     62	CMD_VCO_SET		= 0x10,		/* cmd.len = 12; */
     63	CMD_TUNEREQUEST		= 0x11,		/* cmd.len = 15; */
     64
     65	CMD_MPEG_ONOFF		= 0x13,		/* cmd.len = 4; */
     66	CMD_MPEG_INIT		= 0x14,		/* cmd.len = 7; */
     67	CMD_BANDWIDTH		= 0x15,		/* cmd.len = 12; */
     68	CMD_CLOCK_READ		= 0x16,		/* read clock */
     69	CMD_CLOCK_SET		= 0x17,		/* cmd.len = 10; */
     70
     71	CMD_DISEQC_MSG1		= 0x20,		/* cmd.len = 11; */
     72	CMD_DISEQC_MSG2		= 0x21,		/* cmd.len = d->msg_len + 6; */
     73	CMD_SETVOLTAGE		= 0x22,		/* cmd.len = 2; */
     74	CMD_SETTONE		= 0x23,		/* cmd.len = 4; */
     75	CMD_DISEQC_BURST	= 0x24,		/* cmd.len not used !!! */
     76
     77	CMD_READ_SNR		= 0x1a,		/* Read signal strength */
     78	CMD_START_TUNER		= 0x1b,		/* ??? */
     79
     80	CMD_FWVERSION		= 0x35,
     81
     82	CMD_BER_CTRL		= 0x3c,		/* cmd.len = 0x03; */
     83};
     84
     85#define CX24120_MAX_CMD_LEN	30
     86
     87/* pilot mask */
     88#define CX24120_PILOT_OFF	0x00
     89#define CX24120_PILOT_ON	0x40
     90#define CX24120_PILOT_AUTO	0x80
     91
     92/* signal status */
     93#define CX24120_HAS_SIGNAL	0x01
     94#define CX24120_HAS_CARRIER	0x02
     95#define CX24120_HAS_VITERBI	0x04
     96#define CX24120_HAS_LOCK	0x08
     97#define CX24120_HAS_UNK1	0x10
     98#define CX24120_HAS_UNK2	0x20
     99#define CX24120_STATUS_MASK	0x0f
    100#define CX24120_SIGNAL_MASK	0xc0
    101
    102/* ber window */
    103#define CX24120_BER_WINDOW	16
    104#define CX24120_BER_WSIZE	((1 << CX24120_BER_WINDOW) * 208 * 8)
    105
    106#define info(args...) pr_info("cx24120: " args)
    107#define err(args...)  pr_err("cx24120: ### ERROR: " args)
    108
    109/* The Demod/Tuner can't easily provide these, we cache them */
    110struct cx24120_tuning {
    111	u32 frequency;
    112	u32 symbol_rate;
    113	enum fe_spectral_inversion inversion;
    114	enum fe_code_rate fec;
    115
    116	enum fe_delivery_system delsys;
    117	enum fe_modulation modulation;
    118	enum fe_pilot pilot;
    119
    120	/* Demod values */
    121	u8 fec_val;
    122	u8 fec_mask;
    123	u8 clkdiv;
    124	u8 ratediv;
    125	u8 inversion_val;
    126	u8 pilot_val;
    127};
    128
    129/* Private state */
    130struct cx24120_state {
    131	struct i2c_adapter *i2c;
    132	const struct cx24120_config *config;
    133	struct dvb_frontend frontend;
    134
    135	u8 cold_init;
    136	u8 mpeg_enabled;
    137	u8 need_clock_set;
    138
    139	/* current and next tuning parameters */
    140	struct cx24120_tuning dcur;
    141	struct cx24120_tuning dnxt;
    142
    143	enum fe_status fe_status;
    144
    145	/* dvbv5 stats calculations */
    146	u32 bitrate;
    147	u32 berw_usecs;
    148	u32 ber_prev;
    149	u32 ucb_offset;
    150	unsigned long ber_jiffies_stats;
    151	unsigned long per_jiffies_stats;
    152};
    153
    154/* Command message to firmware */
    155struct cx24120_cmd {
    156	u8 id;
    157	u8 len;
    158	u8 arg[CX24120_MAX_CMD_LEN];
    159};
    160
    161/* Read single register */
    162static int cx24120_readreg(struct cx24120_state *state, u8 reg)
    163{
    164	int ret;
    165	u8 buf = 0;
    166	struct i2c_msg msg[] = {
    167		{
    168			.addr = state->config->i2c_addr,
    169			.flags = 0,
    170			.len = 1,
    171			.buf = &reg
    172		}, {
    173			.addr = state->config->i2c_addr,
    174			.flags = I2C_M_RD,
    175			.len = 1,
    176			.buf = &buf
    177		}
    178	};
    179
    180	ret = i2c_transfer(state->i2c, msg, 2);
    181	if (ret != 2) {
    182		err("Read error: reg=0x%02x, ret=%i)\n", reg, ret);
    183		return ret;
    184	}
    185
    186	dev_dbg(&state->i2c->dev, "reg=0x%02x; data=0x%02x\n", reg, buf);
    187
    188	return buf;
    189}
    190
    191/* Write single register */
    192static int cx24120_writereg(struct cx24120_state *state, u8 reg, u8 data)
    193{
    194	u8 buf[] = { reg, data };
    195	struct i2c_msg msg = {
    196		.addr = state->config->i2c_addr,
    197		.flags = 0,
    198		.buf = buf,
    199		.len = 2
    200	};
    201	int ret;
    202
    203	ret = i2c_transfer(state->i2c, &msg, 1);
    204	if (ret != 1) {
    205		err("Write error: i2c_write error(err == %i, 0x%02x: 0x%02x)\n",
    206		    ret, reg, data);
    207		return ret;
    208	}
    209
    210	dev_dbg(&state->i2c->dev, "reg=0x%02x; data=0x%02x\n", reg, data);
    211
    212	return 0;
    213}
    214
    215/* Write multiple registers in chunks of i2c_wr_max-sized buffers */
    216static int cx24120_writeregs(struct cx24120_state *state,
    217			     u8 reg, const u8 *values, u16 len, u8 incr)
    218{
    219	int ret;
    220	u16 max = state->config->i2c_wr_max > 0 ?
    221				state->config->i2c_wr_max :
    222				len;
    223
    224	struct i2c_msg msg = {
    225		.addr = state->config->i2c_addr,
    226		.flags = 0,
    227	};
    228
    229	msg.buf = kmalloc(max + 1, GFP_KERNEL);
    230	if (!msg.buf)
    231		return -ENOMEM;
    232
    233	while (len) {
    234		msg.buf[0] = reg;
    235		msg.len = len > max ? max : len;
    236		memcpy(&msg.buf[1], values, msg.len);
    237
    238		len    -= msg.len;      /* data length revers counter */
    239		values += msg.len;      /* incr data pointer */
    240
    241		if (incr)
    242			reg += msg.len;
    243		msg.len++;              /* don't forget the addr byte */
    244
    245		ret = i2c_transfer(state->i2c, &msg, 1);
    246		if (ret != 1) {
    247			err("i2c_write error(err == %i, 0x%02x)\n", ret, reg);
    248			goto out;
    249		}
    250
    251		dev_dbg(&state->i2c->dev, "reg=0x%02x; data=%*ph\n",
    252			reg, msg.len - 1, msg.buf + 1);
    253	}
    254
    255	ret = 0;
    256
    257out:
    258	kfree(msg.buf);
    259	return ret;
    260}
    261
    262static const struct dvb_frontend_ops cx24120_ops;
    263
    264struct dvb_frontend *cx24120_attach(const struct cx24120_config *config,
    265				    struct i2c_adapter *i2c)
    266{
    267	struct cx24120_state *state;
    268	int demod_rev;
    269
    270	info("Conexant cx24120/cx24118 - DVBS/S2 Satellite demod/tuner\n");
    271	state = kzalloc(sizeof(*state), GFP_KERNEL);
    272	if (!state) {
    273		err("Unable to allocate memory for cx24120_state\n");
    274		goto error;
    275	}
    276
    277	/* setup the state */
    278	state->config = config;
    279	state->i2c = i2c;
    280
    281	/* check if the demod is present and has proper type */
    282	demod_rev = cx24120_readreg(state, CX24120_REG_REVISION);
    283	switch (demod_rev) {
    284	case 0x07:
    285		info("Demod cx24120 rev. 0x07 detected.\n");
    286		break;
    287	case 0x05:
    288		info("Demod cx24120 rev. 0x05 detected.\n");
    289		break;
    290	default:
    291		err("Unsupported demod revision: 0x%x detected.\n", demod_rev);
    292		goto error;
    293	}
    294
    295	/* create dvb_frontend */
    296	state->cold_init = 0;
    297	memcpy(&state->frontend.ops, &cx24120_ops,
    298	       sizeof(struct dvb_frontend_ops));
    299	state->frontend.demodulator_priv = state;
    300
    301	info("Conexant cx24120/cx24118 attached.\n");
    302	return &state->frontend;
    303
    304error:
    305	kfree(state);
    306	return NULL;
    307}
    308EXPORT_SYMBOL(cx24120_attach);
    309
    310static int cx24120_test_rom(struct cx24120_state *state)
    311{
    312	int err, ret;
    313
    314	err = cx24120_readreg(state, 0xfd);
    315	if (err & 4) {
    316		ret = cx24120_readreg(state, 0xdf) & 0xfe;
    317		err = cx24120_writereg(state, 0xdf, ret);
    318	}
    319	return err;
    320}
    321
    322static int cx24120_read_snr(struct dvb_frontend *fe, u16 *snr)
    323{
    324	struct dtv_frontend_properties *c = &fe->dtv_property_cache;
    325
    326	if (c->cnr.stat[0].scale != FE_SCALE_DECIBEL)
    327		*snr = 0;
    328	else
    329		*snr = div_s64(c->cnr.stat[0].svalue, 100);
    330
    331	return 0;
    332}
    333
    334static int cx24120_read_ber(struct dvb_frontend *fe, u32 *ber)
    335{
    336	struct cx24120_state *state = fe->demodulator_priv;
    337	struct dtv_frontend_properties *c = &fe->dtv_property_cache;
    338
    339	if (c->post_bit_error.stat[0].scale != FE_SCALE_COUNTER) {
    340		*ber = 0;
    341		return 0;
    342	}
    343
    344	*ber = c->post_bit_error.stat[0].uvalue - state->ber_prev;
    345	state->ber_prev = c->post_bit_error.stat[0].uvalue;
    346
    347	return 0;
    348}
    349
    350static int cx24120_msg_mpeg_output_global_config(struct cx24120_state *state,
    351						 u8 flag);
    352
    353/* Check if we're running a command that needs to disable mpeg out */
    354static void cx24120_check_cmd(struct cx24120_state *state, u8 id)
    355{
    356	switch (id) {
    357	case CMD_TUNEREQUEST:
    358	case CMD_CLOCK_READ:
    359	case CMD_DISEQC_MSG1:
    360	case CMD_DISEQC_MSG2:
    361	case CMD_SETVOLTAGE:
    362	case CMD_SETTONE:
    363	case CMD_DISEQC_BURST:
    364		cx24120_msg_mpeg_output_global_config(state, 0);
    365		/* Old driver would do a msleep(100) here */
    366		return;
    367	default:
    368		return;
    369	}
    370}
    371
    372/* Send a message to the firmware */
    373static int cx24120_message_send(struct cx24120_state *state,
    374				struct cx24120_cmd *cmd)
    375{
    376	int ficus;
    377
    378	if (state->mpeg_enabled) {
    379		/* Disable mpeg out on certain commands */
    380		cx24120_check_cmd(state, cmd->id);
    381	}
    382
    383	cx24120_writereg(state, CX24120_REG_CMD_START, cmd->id);
    384	cx24120_writeregs(state, CX24120_REG_CMD_ARGS, &cmd->arg[0],
    385			  cmd->len, 1);
    386	cx24120_writereg(state, CX24120_REG_CMD_END, 0x01);
    387
    388	ficus = 1000;
    389	while (cx24120_readreg(state, CX24120_REG_CMD_END)) {
    390		msleep(20);
    391		ficus -= 20;
    392		if (ficus == 0) {
    393			err("Error sending message to firmware\n");
    394			return -EREMOTEIO;
    395		}
    396	}
    397	dev_dbg(&state->i2c->dev, "sent message 0x%02x\n", cmd->id);
    398
    399	return 0;
    400}
    401
    402/* Send a message and fill arg[] with the results */
    403static int cx24120_message_sendrcv(struct cx24120_state *state,
    404				   struct cx24120_cmd *cmd, u8 numreg)
    405{
    406	int ret, i;
    407
    408	if (numreg > CX24120_MAX_CMD_LEN) {
    409		err("Too many registers to read. cmd->reg = %d", numreg);
    410		return -EREMOTEIO;
    411	}
    412
    413	ret = cx24120_message_send(state, cmd);
    414	if (ret != 0)
    415		return ret;
    416
    417	if (!numreg)
    418		return 0;
    419
    420	/* Read numreg registers starting from register cmd->len */
    421	for (i = 0; i < numreg; i++)
    422		cmd->arg[i] = cx24120_readreg(state, (cmd->len + i + 1));
    423
    424	return 0;
    425}
    426
    427static int cx24120_read_signal_strength(struct dvb_frontend *fe,
    428					u16 *signal_strength)
    429{
    430	struct dtv_frontend_properties *c = &fe->dtv_property_cache;
    431
    432	if (c->strength.stat[0].scale != FE_SCALE_RELATIVE)
    433		*signal_strength = 0;
    434	else
    435		*signal_strength = c->strength.stat[0].uvalue;
    436
    437	return 0;
    438}
    439
    440static int cx24120_msg_mpeg_output_global_config(struct cx24120_state *state,
    441						 u8 enable)
    442{
    443	struct cx24120_cmd cmd;
    444	int ret;
    445
    446	cmd.id = CMD_MPEG_ONOFF;
    447	cmd.len = 4;
    448	cmd.arg[0] = 0x01;
    449	cmd.arg[1] = 0x00;
    450	cmd.arg[2] = enable ? 0 : (u8)(-1);
    451	cmd.arg[3] = 0x01;
    452
    453	ret = cx24120_message_send(state, &cmd);
    454	if (ret != 0) {
    455		dev_dbg(&state->i2c->dev, "failed to %s MPEG output\n",
    456			enable ? "enable" : "disable");
    457		return ret;
    458	}
    459
    460	state->mpeg_enabled = enable;
    461	dev_dbg(&state->i2c->dev, "MPEG output %s\n",
    462		enable ? "enabled" : "disabled");
    463
    464	return 0;
    465}
    466
    467static int cx24120_msg_mpeg_output_config(struct cx24120_state *state, u8 seq)
    468{
    469	struct cx24120_cmd cmd;
    470	struct cx24120_initial_mpeg_config i =
    471			state->config->initial_mpeg_config;
    472
    473	cmd.id = CMD_MPEG_INIT;
    474	cmd.len = 7;
    475	cmd.arg[0] = seq; /* sequental number - can be 0,1,2 */
    476	cmd.arg[1] = ((i.x1 & 0x01) << 1) | ((i.x1 >> 1) & 0x01);
    477	cmd.arg[2] = 0x05;
    478	cmd.arg[3] = 0x02;
    479	cmd.arg[4] = ((i.x2 >> 1) & 0x01);
    480	cmd.arg[5] = (i.x2 & 0xf0) | (i.x3 & 0x0f);
    481	cmd.arg[6] = 0x10;
    482
    483	return cx24120_message_send(state, &cmd);
    484}
    485
    486static int cx24120_diseqc_send_burst(struct dvb_frontend *fe,
    487				     enum fe_sec_mini_cmd burst)
    488{
    489	struct cx24120_state *state = fe->demodulator_priv;
    490	struct cx24120_cmd cmd;
    491
    492	dev_dbg(&state->i2c->dev, "\n");
    493
    494	/*
    495	 * Yes, cmd.len is set to zero. The old driver
    496	 * didn't specify any len, but also had a
    497	 * memset 0 before every use of the cmd struct
    498	 * which would have set it to zero.
    499	 * This quite probably needs looking into.
    500	 */
    501	cmd.id = CMD_DISEQC_BURST;
    502	cmd.len = 0;
    503	cmd.arg[0] = 0x00;
    504	cmd.arg[1] = (burst == SEC_MINI_B) ? 0x01 : 0x00;
    505
    506	return cx24120_message_send(state, &cmd);
    507}
    508
    509static int cx24120_set_tone(struct dvb_frontend *fe, enum fe_sec_tone_mode tone)
    510{
    511	struct cx24120_state *state = fe->demodulator_priv;
    512	struct cx24120_cmd cmd;
    513
    514	dev_dbg(&state->i2c->dev, "(%d)\n", tone);
    515
    516	if ((tone != SEC_TONE_ON) && (tone != SEC_TONE_OFF)) {
    517		err("Invalid tone=%d\n", tone);
    518		return -EINVAL;
    519	}
    520
    521	cmd.id = CMD_SETTONE;
    522	cmd.len = 4;
    523	cmd.arg[0] = 0x00;
    524	cmd.arg[1] = 0x00;
    525	cmd.arg[2] = 0x00;
    526	cmd.arg[3] = (tone == SEC_TONE_ON) ? 0x01 : 0x00;
    527
    528	return cx24120_message_send(state, &cmd);
    529}
    530
    531static int cx24120_set_voltage(struct dvb_frontend *fe,
    532			       enum fe_sec_voltage voltage)
    533{
    534	struct cx24120_state *state = fe->demodulator_priv;
    535	struct cx24120_cmd cmd;
    536
    537	dev_dbg(&state->i2c->dev, "(%d)\n", voltage);
    538
    539	cmd.id = CMD_SETVOLTAGE;
    540	cmd.len = 2;
    541	cmd.arg[0] = 0x00;
    542	cmd.arg[1] = (voltage == SEC_VOLTAGE_18) ? 0x01 : 0x00;
    543
    544	return cx24120_message_send(state, &cmd);
    545}
    546
    547static int cx24120_send_diseqc_msg(struct dvb_frontend *fe,
    548				   struct dvb_diseqc_master_cmd *d)
    549{
    550	struct cx24120_state *state = fe->demodulator_priv;
    551	struct cx24120_cmd cmd;
    552	int back_count;
    553
    554	dev_dbg(&state->i2c->dev, "\n");
    555
    556	cmd.id = CMD_DISEQC_MSG1;
    557	cmd.len = 11;
    558	cmd.arg[0] = 0x00;
    559	cmd.arg[1] = 0x00;
    560	cmd.arg[2] = 0x03;
    561	cmd.arg[3] = 0x16;
    562	cmd.arg[4] = 0x28;
    563	cmd.arg[5] = 0x01;
    564	cmd.arg[6] = 0x01;
    565	cmd.arg[7] = 0x14;
    566	cmd.arg[8] = 0x19;
    567	cmd.arg[9] = 0x14;
    568	cmd.arg[10] = 0x1e;
    569
    570	if (cx24120_message_send(state, &cmd)) {
    571		err("send 1st message(0x%x) failed\n", cmd.id);
    572		return -EREMOTEIO;
    573	}
    574
    575	cmd.id = CMD_DISEQC_MSG2;
    576	cmd.len = d->msg_len + 6;
    577	cmd.arg[0] = 0x00;
    578	cmd.arg[1] = 0x01;
    579	cmd.arg[2] = 0x02;
    580	cmd.arg[3] = 0x00;
    581	cmd.arg[4] = 0x00;
    582	cmd.arg[5] = d->msg_len;
    583
    584	memcpy(&cmd.arg[6], &d->msg, d->msg_len);
    585
    586	if (cx24120_message_send(state, &cmd)) {
    587		err("send 2nd message(0x%x) failed\n", cmd.id);
    588		return -EREMOTEIO;
    589	}
    590
    591	back_count = 500;
    592	do {
    593		if (!(cx24120_readreg(state, 0x93) & 0x01)) {
    594			dev_dbg(&state->i2c->dev, "diseqc sequence sent\n");
    595			return 0;
    596		}
    597		msleep(20);
    598		back_count -= 20;
    599	} while (back_count);
    600
    601	err("Too long waiting for diseqc.\n");
    602	return -ETIMEDOUT;
    603}
    604
    605static void cx24120_get_stats(struct cx24120_state *state)
    606{
    607	struct dvb_frontend *fe = &state->frontend;
    608	struct dtv_frontend_properties *c = &fe->dtv_property_cache;
    609	struct cx24120_cmd cmd;
    610	int ret, cnr, msecs;
    611	u16 sig, ucb;
    612	u32 ber;
    613
    614	dev_dbg(&state->i2c->dev, "\n");
    615
    616	/* signal strength */
    617	if (state->fe_status & FE_HAS_SIGNAL) {
    618		cmd.id = CMD_READ_SNR;
    619		cmd.len = 1;
    620		cmd.arg[0] = 0x00;
    621
    622		ret = cx24120_message_send(state, &cmd);
    623		if (ret != 0) {
    624			err("error reading signal strength\n");
    625			return;
    626		}
    627
    628		/* raw */
    629		sig = cx24120_readreg(state, CX24120_REG_SIGSTR_H) >> 6;
    630		sig = sig << 8;
    631		sig |= cx24120_readreg(state, CX24120_REG_SIGSTR_L);
    632		dev_dbg(&state->i2c->dev,
    633			"signal strength from firmware = 0x%x\n", sig);
    634
    635		/* cooked */
    636		sig = -100 * sig + 94324;
    637
    638		c->strength.stat[0].scale = FE_SCALE_RELATIVE;
    639		c->strength.stat[0].uvalue = sig;
    640	} else {
    641		c->strength.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
    642	}
    643
    644	/* CNR */
    645	if (state->fe_status & FE_HAS_VITERBI) {
    646		cnr = cx24120_readreg(state, CX24120_REG_QUALITY_H) << 8;
    647		cnr |= cx24120_readreg(state, CX24120_REG_QUALITY_L);
    648		dev_dbg(&state->i2c->dev, "read SNR index = %d\n", cnr);
    649
    650		/* guessed - seems about right */
    651		cnr = cnr * 100;
    652
    653		c->cnr.stat[0].scale = FE_SCALE_DECIBEL;
    654		c->cnr.stat[0].svalue = cnr;
    655	} else {
    656		c->cnr.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
    657	}
    658
    659	/* BER & UCB require lock */
    660	if (!(state->fe_status & FE_HAS_LOCK)) {
    661		c->post_bit_error.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
    662		c->post_bit_count.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
    663		c->block_error.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
    664		c->block_count.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
    665		return;
    666	}
    667
    668	/* BER */
    669	if (time_after(jiffies, state->ber_jiffies_stats)) {
    670		msecs = (state->berw_usecs + 500) / 1000;
    671		state->ber_jiffies_stats = jiffies + msecs_to_jiffies(msecs);
    672
    673		ber = cx24120_readreg(state, CX24120_REG_BER_HH) << 24;
    674		ber |= cx24120_readreg(state, CX24120_REG_BER_HL) << 16;
    675		ber |= cx24120_readreg(state, CX24120_REG_BER_LH) << 8;
    676		ber |= cx24120_readreg(state, CX24120_REG_BER_LL);
    677		dev_dbg(&state->i2c->dev, "read BER index = %d\n", ber);
    678
    679		c->post_bit_error.stat[0].scale = FE_SCALE_COUNTER;
    680		c->post_bit_error.stat[0].uvalue += ber;
    681
    682		c->post_bit_count.stat[0].scale = FE_SCALE_COUNTER;
    683		c->post_bit_count.stat[0].uvalue += CX24120_BER_WSIZE;
    684	}
    685
    686	/* UCB */
    687	if (time_after(jiffies, state->per_jiffies_stats)) {
    688		state->per_jiffies_stats = jiffies + msecs_to_jiffies(1000);
    689
    690		ucb = cx24120_readreg(state, CX24120_REG_UCB_H) << 8;
    691		ucb |= cx24120_readreg(state, CX24120_REG_UCB_L);
    692		dev_dbg(&state->i2c->dev, "ucblocks = %d\n", ucb);
    693
    694		/* handle reset */
    695		if (ucb < state->ucb_offset)
    696			state->ucb_offset = c->block_error.stat[0].uvalue;
    697
    698		c->block_error.stat[0].scale = FE_SCALE_COUNTER;
    699		c->block_error.stat[0].uvalue = ucb + state->ucb_offset;
    700
    701		c->block_count.stat[0].scale = FE_SCALE_COUNTER;
    702		c->block_count.stat[0].uvalue += state->bitrate / 8 / 208;
    703	}
    704}
    705
    706static void cx24120_set_clock_ratios(struct dvb_frontend *fe);
    707
    708/* Read current tuning status */
    709static int cx24120_read_status(struct dvb_frontend *fe, enum fe_status *status)
    710{
    711	struct cx24120_state *state = fe->demodulator_priv;
    712	int lock;
    713
    714	lock = cx24120_readreg(state, CX24120_REG_STATUS);
    715
    716	dev_dbg(&state->i2c->dev, "status = 0x%02x\n", lock);
    717
    718	*status = 0;
    719
    720	if (lock & CX24120_HAS_SIGNAL)
    721		*status = FE_HAS_SIGNAL;
    722	if (lock & CX24120_HAS_CARRIER)
    723		*status |= FE_HAS_CARRIER;
    724	if (lock & CX24120_HAS_VITERBI)
    725		*status |= FE_HAS_VITERBI | FE_HAS_SYNC;
    726	if (lock & CX24120_HAS_LOCK)
    727		*status |= FE_HAS_LOCK;
    728
    729	/*
    730	 * TODO: is FE_HAS_SYNC in the right place?
    731	 * Other cx241xx drivers have this slightly
    732	 * different
    733	 */
    734
    735	state->fe_status = *status;
    736	cx24120_get_stats(state);
    737
    738	/* Set the clock once tuned in */
    739	if (state->need_clock_set && *status & FE_HAS_LOCK) {
    740		/* Set clock ratios */
    741		cx24120_set_clock_ratios(fe);
    742
    743		/* Old driver would do a msleep(200) here */
    744
    745		/* Renable mpeg output */
    746		if (!state->mpeg_enabled)
    747			cx24120_msg_mpeg_output_global_config(state, 1);
    748
    749		state->need_clock_set = 0;
    750	}
    751
    752	return 0;
    753}
    754
    755/*
    756 * FEC & modulation lookup table
    757 * Used for decoding the REG_FECMODE register
    758 * once tuned in.
    759 */
    760struct cx24120_modfec {
    761	enum fe_delivery_system delsys;
    762	enum fe_modulation mod;
    763	enum fe_code_rate fec;
    764	u8 val;
    765};
    766
    767static const struct cx24120_modfec modfec_lookup_table[] = {
    768	/*delsys     mod    fec       val */
    769	{ SYS_DVBS,  QPSK,  FEC_1_2,  0x01 },
    770	{ SYS_DVBS,  QPSK,  FEC_2_3,  0x02 },
    771	{ SYS_DVBS,  QPSK,  FEC_3_4,  0x03 },
    772	{ SYS_DVBS,  QPSK,  FEC_4_5,  0x04 },
    773	{ SYS_DVBS,  QPSK,  FEC_5_6,  0x05 },
    774	{ SYS_DVBS,  QPSK,  FEC_6_7,  0x06 },
    775	{ SYS_DVBS,  QPSK,  FEC_7_8,  0x07 },
    776
    777	{ SYS_DVBS2, QPSK,  FEC_1_2,  0x04 },
    778	{ SYS_DVBS2, QPSK,  FEC_3_5,  0x05 },
    779	{ SYS_DVBS2, QPSK,  FEC_2_3,  0x06 },
    780	{ SYS_DVBS2, QPSK,  FEC_3_4,  0x07 },
    781	{ SYS_DVBS2, QPSK,  FEC_4_5,  0x08 },
    782	{ SYS_DVBS2, QPSK,  FEC_5_6,  0x09 },
    783	{ SYS_DVBS2, QPSK,  FEC_8_9,  0x0a },
    784	{ SYS_DVBS2, QPSK,  FEC_9_10, 0x0b },
    785
    786	{ SYS_DVBS2, PSK_8, FEC_3_5,  0x0c },
    787	{ SYS_DVBS2, PSK_8, FEC_2_3,  0x0d },
    788	{ SYS_DVBS2, PSK_8, FEC_3_4,  0x0e },
    789	{ SYS_DVBS2, PSK_8, FEC_5_6,  0x0f },
    790	{ SYS_DVBS2, PSK_8, FEC_8_9,  0x10 },
    791	{ SYS_DVBS2, PSK_8, FEC_9_10, 0x11 },
    792};
    793
    794/* Retrieve current fec, modulation & pilot values */
    795static int cx24120_get_fec(struct dvb_frontend *fe)
    796{
    797	struct dtv_frontend_properties *c = &fe->dtv_property_cache;
    798	struct cx24120_state *state = fe->demodulator_priv;
    799	int idx;
    800	int ret;
    801	int fec;
    802
    803	ret = cx24120_readreg(state, CX24120_REG_FECMODE);
    804	fec = ret & 0x3f; /* Lower 6 bits */
    805
    806	dev_dbg(&state->i2c->dev, "raw fec = %d\n", fec);
    807
    808	for (idx = 0; idx < ARRAY_SIZE(modfec_lookup_table); idx++) {
    809		if (modfec_lookup_table[idx].delsys != state->dcur.delsys)
    810			continue;
    811		if (modfec_lookup_table[idx].val != fec)
    812			continue;
    813
    814		break; /* found */
    815	}
    816
    817	if (idx >= ARRAY_SIZE(modfec_lookup_table)) {
    818		dev_dbg(&state->i2c->dev, "couldn't find fec!\n");
    819		return -EINVAL;
    820	}
    821
    822	/* save values back to cache */
    823	c->modulation = modfec_lookup_table[idx].mod;
    824	c->fec_inner = modfec_lookup_table[idx].fec;
    825	c->pilot = (ret & 0x80) ? PILOT_ON : PILOT_OFF;
    826
    827	dev_dbg(&state->i2c->dev, "mod(%d), fec(%d), pilot(%d)\n",
    828		c->modulation, c->fec_inner, c->pilot);
    829
    830	return 0;
    831}
    832
    833/* Calculate ber window time */
    834static void cx24120_calculate_ber_window(struct cx24120_state *state, u32 rate)
    835{
    836	struct dvb_frontend *fe = &state->frontend;
    837	struct dtv_frontend_properties *c = &fe->dtv_property_cache;
    838	u64 tmp;
    839
    840	/*
    841	 * Calculate bitrate from rate in the clock ratios table.
    842	 * This isn't *exactly* right but close enough.
    843	 */
    844	tmp = (u64)c->symbol_rate * rate;
    845	do_div(tmp, 256);
    846	state->bitrate = tmp;
    847
    848	/* usecs per ber window */
    849	tmp = 1000000ULL * CX24120_BER_WSIZE;
    850	do_div(tmp, state->bitrate);
    851	state->berw_usecs = tmp;
    852
    853	dev_dbg(&state->i2c->dev, "bitrate: %u, berw_usecs: %u\n",
    854		state->bitrate, state->berw_usecs);
    855}
    856
    857/*
    858 * Clock ratios lookup table
    859 *
    860 * Values obtained from much larger table in old driver
    861 * which had numerous entries which would never match.
    862 *
    863 * There's probably some way of calculating these but I
    864 * can't determine the pattern
    865 */
    866struct cx24120_clock_ratios_table {
    867	enum fe_delivery_system delsys;
    868	enum fe_pilot pilot;
    869	enum fe_modulation mod;
    870	enum fe_code_rate fec;
    871	u32 m_rat;
    872	u32 n_rat;
    873	u32 rate;
    874};
    875
    876static const struct cx24120_clock_ratios_table clock_ratios_table[] = {
    877	/*delsys     pilot      mod    fec       m_rat    n_rat   rate */
    878	{ SYS_DVBS2, PILOT_OFF, QPSK,  FEC_1_2,  273088,  254505, 274 },
    879	{ SYS_DVBS2, PILOT_OFF, QPSK,  FEC_3_5,  17272,   13395,  330 },
    880	{ SYS_DVBS2, PILOT_OFF, QPSK,  FEC_2_3,  24344,   16967,  367 },
    881	{ SYS_DVBS2, PILOT_OFF, QPSK,  FEC_3_4,  410788,  254505, 413 },
    882	{ SYS_DVBS2, PILOT_OFF, QPSK,  FEC_4_5,  438328,  254505, 440 },
    883	{ SYS_DVBS2, PILOT_OFF, QPSK,  FEC_5_6,  30464,   16967,  459 },
    884	{ SYS_DVBS2, PILOT_OFF, QPSK,  FEC_8_9,  487832,  254505, 490 },
    885	{ SYS_DVBS2, PILOT_OFF, QPSK,  FEC_9_10, 493952,  254505, 496 },
    886	{ SYS_DVBS2, PILOT_OFF, PSK_8, FEC_3_5,  328168,  169905, 494 },
    887	{ SYS_DVBS2, PILOT_OFF, PSK_8, FEC_2_3,  24344,   11327,  550 },
    888	{ SYS_DVBS2, PILOT_OFF, PSK_8, FEC_3_4,  410788,  169905, 618 },
    889	{ SYS_DVBS2, PILOT_OFF, PSK_8, FEC_5_6,  30464,   11327,  688 },
    890	{ SYS_DVBS2, PILOT_OFF, PSK_8, FEC_8_9,  487832,  169905, 735 },
    891	{ SYS_DVBS2, PILOT_OFF, PSK_8, FEC_9_10, 493952,  169905, 744 },
    892	{ SYS_DVBS2, PILOT_ON,  QPSK,  FEC_1_2,  273088,  260709, 268 },
    893	{ SYS_DVBS2, PILOT_ON,  QPSK,  FEC_3_5,  328168,  260709, 322 },
    894	{ SYS_DVBS2, PILOT_ON,  QPSK,  FEC_2_3,  121720,  86903,  358 },
    895	{ SYS_DVBS2, PILOT_ON,  QPSK,  FEC_3_4,  410788,  260709, 403 },
    896	{ SYS_DVBS2, PILOT_ON,  QPSK,  FEC_4_5,  438328,  260709, 430 },
    897	{ SYS_DVBS2, PILOT_ON,  QPSK,  FEC_5_6,  152320,  86903,  448 },
    898	{ SYS_DVBS2, PILOT_ON,  QPSK,  FEC_8_9,  487832,  260709, 479 },
    899	{ SYS_DVBS2, PILOT_ON,  QPSK,  FEC_9_10, 493952,  260709, 485 },
    900	{ SYS_DVBS2, PILOT_ON,  PSK_8, FEC_3_5,  328168,  173853, 483 },
    901	{ SYS_DVBS2, PILOT_ON,  PSK_8, FEC_2_3,  121720,  57951,  537 },
    902	{ SYS_DVBS2, PILOT_ON,  PSK_8, FEC_3_4,  410788,  173853, 604 },
    903	{ SYS_DVBS2, PILOT_ON,  PSK_8, FEC_5_6,  152320,  57951,  672 },
    904	{ SYS_DVBS2, PILOT_ON,  PSK_8, FEC_8_9,  487832,  173853, 718 },
    905	{ SYS_DVBS2, PILOT_ON,  PSK_8, FEC_9_10, 493952,  173853, 727 },
    906	{ SYS_DVBS,  PILOT_OFF, QPSK,  FEC_1_2,  152592,  152592, 256 },
    907	{ SYS_DVBS,  PILOT_OFF, QPSK,  FEC_2_3,  305184,  228888, 341 },
    908	{ SYS_DVBS,  PILOT_OFF, QPSK,  FEC_3_4,  457776,  305184, 384 },
    909	{ SYS_DVBS,  PILOT_OFF, QPSK,  FEC_5_6,  762960,  457776, 427 },
    910	{ SYS_DVBS,  PILOT_OFF, QPSK,  FEC_7_8,  1068144, 610368, 448 },
    911};
    912
    913/* Set clock ratio from lookup table */
    914static void cx24120_set_clock_ratios(struct dvb_frontend *fe)
    915{
    916	struct dtv_frontend_properties *c = &fe->dtv_property_cache;
    917	struct cx24120_state *state = fe->demodulator_priv;
    918	struct cx24120_cmd cmd;
    919	int ret, idx;
    920
    921	/* Find fec, modulation, pilot */
    922	ret = cx24120_get_fec(fe);
    923	if (ret != 0)
    924		return;
    925
    926	/* Find the clock ratios in the lookup table */
    927	for (idx = 0; idx < ARRAY_SIZE(clock_ratios_table); idx++) {
    928		if (clock_ratios_table[idx].delsys != state->dcur.delsys)
    929			continue;
    930		if (clock_ratios_table[idx].mod != c->modulation)
    931			continue;
    932		if (clock_ratios_table[idx].fec != c->fec_inner)
    933			continue;
    934		if (clock_ratios_table[idx].pilot != c->pilot)
    935			continue;
    936
    937		break;		/* found */
    938	}
    939
    940	if (idx >= ARRAY_SIZE(clock_ratios_table)) {
    941		info("Clock ratio not found - data reception in danger\n");
    942		return;
    943	}
    944
    945	/* Read current values? */
    946	cmd.id = CMD_CLOCK_READ;
    947	cmd.len = 1;
    948	cmd.arg[0] = 0x00;
    949	ret = cx24120_message_sendrcv(state, &cmd, 6);
    950	if (ret != 0)
    951		return;
    952	/* in cmd[0]-[5] - result */
    953
    954	dev_dbg(&state->i2c->dev, "m=%d, n=%d; idx: %d m=%d, n=%d, rate=%d\n",
    955		cmd.arg[2] | (cmd.arg[1] << 8) | (cmd.arg[0] << 16),
    956		cmd.arg[5] | (cmd.arg[4] << 8) | (cmd.arg[3] << 16),
    957		idx,
    958		clock_ratios_table[idx].m_rat,
    959		clock_ratios_table[idx].n_rat,
    960		clock_ratios_table[idx].rate);
    961
    962	/* Set the clock */
    963	cmd.id = CMD_CLOCK_SET;
    964	cmd.len = 10;
    965	cmd.arg[0] = 0;
    966	cmd.arg[1] = 0x10;
    967	cmd.arg[2] = (clock_ratios_table[idx].m_rat >> 16) & 0xff;
    968	cmd.arg[3] = (clock_ratios_table[idx].m_rat >>  8) & 0xff;
    969	cmd.arg[4] = (clock_ratios_table[idx].m_rat >>  0) & 0xff;
    970	cmd.arg[5] = (clock_ratios_table[idx].n_rat >> 16) & 0xff;
    971	cmd.arg[6] = (clock_ratios_table[idx].n_rat >>  8) & 0xff;
    972	cmd.arg[7] = (clock_ratios_table[idx].n_rat >>  0) & 0xff;
    973	cmd.arg[8] = (clock_ratios_table[idx].rate >> 8) & 0xff;
    974	cmd.arg[9] = (clock_ratios_table[idx].rate >> 0) & 0xff;
    975
    976	cx24120_message_send(state, &cmd);
    977
    978	/* Calculate ber window rates for stat work */
    979	cx24120_calculate_ber_window(state, clock_ratios_table[idx].rate);
    980}
    981
    982/* Set inversion value */
    983static int cx24120_set_inversion(struct cx24120_state *state,
    984				 enum fe_spectral_inversion inversion)
    985{
    986	dev_dbg(&state->i2c->dev, "(%d)\n", inversion);
    987
    988	switch (inversion) {
    989	case INVERSION_OFF:
    990		state->dnxt.inversion_val = 0x00;
    991		break;
    992	case INVERSION_ON:
    993		state->dnxt.inversion_val = 0x04;
    994		break;
    995	case INVERSION_AUTO:
    996		state->dnxt.inversion_val = 0x0c;
    997		break;
    998	default:
    999		return -EINVAL;
   1000	}
   1001
   1002	state->dnxt.inversion = inversion;
   1003
   1004	return 0;
   1005}
   1006
   1007/* FEC lookup table for tuning */
   1008struct cx24120_modfec_table {
   1009	enum fe_delivery_system delsys;
   1010	enum fe_modulation mod;
   1011	enum fe_code_rate fec;
   1012	u8 val;
   1013};
   1014
   1015static const struct cx24120_modfec_table modfec_table[] = {
   1016	/*delsys     mod    fec       val */
   1017	{ SYS_DVBS,  QPSK,  FEC_1_2,  0x2e },
   1018	{ SYS_DVBS,  QPSK,  FEC_2_3,  0x2f },
   1019	{ SYS_DVBS,  QPSK,  FEC_3_4,  0x30 },
   1020	{ SYS_DVBS,  QPSK,  FEC_5_6,  0x31 },
   1021	{ SYS_DVBS,  QPSK,  FEC_6_7,  0x32 },
   1022	{ SYS_DVBS,  QPSK,  FEC_7_8,  0x33 },
   1023
   1024	{ SYS_DVBS2, QPSK,  FEC_1_2,  0x04 },
   1025	{ SYS_DVBS2, QPSK,  FEC_3_5,  0x05 },
   1026	{ SYS_DVBS2, QPSK,  FEC_2_3,  0x06 },
   1027	{ SYS_DVBS2, QPSK,  FEC_3_4,  0x07 },
   1028	{ SYS_DVBS2, QPSK,  FEC_4_5,  0x08 },
   1029	{ SYS_DVBS2, QPSK,  FEC_5_6,  0x09 },
   1030	{ SYS_DVBS2, QPSK,  FEC_8_9,  0x0a },
   1031	{ SYS_DVBS2, QPSK,  FEC_9_10, 0x0b },
   1032
   1033	{ SYS_DVBS2, PSK_8, FEC_3_5,  0x0c },
   1034	{ SYS_DVBS2, PSK_8, FEC_2_3,  0x0d },
   1035	{ SYS_DVBS2, PSK_8, FEC_3_4,  0x0e },
   1036	{ SYS_DVBS2, PSK_8, FEC_5_6,  0x0f },
   1037	{ SYS_DVBS2, PSK_8, FEC_8_9,  0x10 },
   1038	{ SYS_DVBS2, PSK_8, FEC_9_10, 0x11 },
   1039};
   1040
   1041/* Set fec_val & fec_mask values from delsys, modulation & fec */
   1042static int cx24120_set_fec(struct cx24120_state *state, enum fe_modulation mod,
   1043			   enum fe_code_rate fec)
   1044{
   1045	int idx;
   1046
   1047	dev_dbg(&state->i2c->dev, "(0x%02x,0x%02x)\n", mod, fec);
   1048
   1049	state->dnxt.fec = fec;
   1050
   1051	/* Lookup fec_val from modfec table */
   1052	for (idx = 0; idx < ARRAY_SIZE(modfec_table); idx++) {
   1053		if (modfec_table[idx].delsys != state->dnxt.delsys)
   1054			continue;
   1055		if (modfec_table[idx].mod != mod)
   1056			continue;
   1057		if (modfec_table[idx].fec != fec)
   1058			continue;
   1059
   1060		/* found */
   1061		state->dnxt.fec_mask = 0x00;
   1062		state->dnxt.fec_val = modfec_table[idx].val;
   1063		return 0;
   1064	}
   1065
   1066	if (state->dnxt.delsys == SYS_DVBS2) {
   1067		/* DVBS2 auto is 0x00/0x00 */
   1068		state->dnxt.fec_mask = 0x00;
   1069		state->dnxt.fec_val  = 0x00;
   1070	} else {
   1071		/* Set DVB-S to auto */
   1072		state->dnxt.fec_val  = 0x2e;
   1073		state->dnxt.fec_mask = 0xac;
   1074	}
   1075
   1076	return 0;
   1077}
   1078
   1079/* Set pilot */
   1080static int cx24120_set_pilot(struct cx24120_state *state, enum fe_pilot pilot)
   1081{
   1082	dev_dbg(&state->i2c->dev, "(%d)\n", pilot);
   1083
   1084	/* Pilot only valid in DVBS2 */
   1085	if (state->dnxt.delsys != SYS_DVBS2) {
   1086		state->dnxt.pilot_val = CX24120_PILOT_OFF;
   1087		return 0;
   1088	}
   1089
   1090	switch (pilot) {
   1091	case PILOT_OFF:
   1092		state->dnxt.pilot_val = CX24120_PILOT_OFF;
   1093		break;
   1094	case PILOT_ON:
   1095		state->dnxt.pilot_val = CX24120_PILOT_ON;
   1096		break;
   1097	case PILOT_AUTO:
   1098	default:
   1099		state->dnxt.pilot_val = CX24120_PILOT_AUTO;
   1100	}
   1101
   1102	return 0;
   1103}
   1104
   1105/* Set symbol rate */
   1106static int cx24120_set_symbolrate(struct cx24120_state *state, u32 rate)
   1107{
   1108	dev_dbg(&state->i2c->dev, "(%d)\n", rate);
   1109
   1110	state->dnxt.symbol_rate = rate;
   1111
   1112	/* Check symbol rate */
   1113	if (rate  > 31000000) {
   1114		state->dnxt.clkdiv  = (-(rate < 31000001) & 3) + 2;
   1115		state->dnxt.ratediv = (-(rate < 31000001) & 6) + 4;
   1116	} else {
   1117		state->dnxt.clkdiv  = 3;
   1118		state->dnxt.ratediv = 6;
   1119	}
   1120
   1121	return 0;
   1122}
   1123
   1124/* Overwrite the current tuning params, we are about to tune */
   1125static void cx24120_clone_params(struct dvb_frontend *fe)
   1126{
   1127	struct cx24120_state *state = fe->demodulator_priv;
   1128
   1129	state->dcur = state->dnxt;
   1130}
   1131
   1132static int cx24120_set_frontend(struct dvb_frontend *fe)
   1133{
   1134	struct dtv_frontend_properties *c = &fe->dtv_property_cache;
   1135	struct cx24120_state *state = fe->demodulator_priv;
   1136	struct cx24120_cmd cmd;
   1137	int ret;
   1138
   1139	switch (c->delivery_system) {
   1140	case SYS_DVBS2:
   1141		dev_dbg(&state->i2c->dev, "DVB-S2\n");
   1142		break;
   1143	case SYS_DVBS:
   1144		dev_dbg(&state->i2c->dev, "DVB-S\n");
   1145		break;
   1146	default:
   1147		dev_dbg(&state->i2c->dev,
   1148			"delivery system(%d) not supported\n",
   1149			c->delivery_system);
   1150		return -EINVAL;
   1151	}
   1152
   1153	state->dnxt.delsys = c->delivery_system;
   1154	state->dnxt.modulation = c->modulation;
   1155	state->dnxt.frequency = c->frequency;
   1156	state->dnxt.pilot = c->pilot;
   1157
   1158	ret = cx24120_set_inversion(state, c->inversion);
   1159	if (ret !=  0)
   1160		return ret;
   1161
   1162	ret = cx24120_set_fec(state, c->modulation, c->fec_inner);
   1163	if (ret !=  0)
   1164		return ret;
   1165
   1166	ret = cx24120_set_pilot(state, c->pilot);
   1167	if (ret != 0)
   1168		return ret;
   1169
   1170	ret = cx24120_set_symbolrate(state, c->symbol_rate);
   1171	if (ret !=  0)
   1172		return ret;
   1173
   1174	/* discard the 'current' tuning parameters and prepare to tune */
   1175	cx24120_clone_params(fe);
   1176
   1177	dev_dbg(&state->i2c->dev,
   1178		"delsys      = %d\n", state->dcur.delsys);
   1179	dev_dbg(&state->i2c->dev,
   1180		"modulation  = %d\n", state->dcur.modulation);
   1181	dev_dbg(&state->i2c->dev,
   1182		"frequency   = %d\n", state->dcur.frequency);
   1183	dev_dbg(&state->i2c->dev,
   1184		"pilot       = %d (val = 0x%02x)\n",
   1185		state->dcur.pilot, state->dcur.pilot_val);
   1186	dev_dbg(&state->i2c->dev,
   1187		"symbol_rate = %d (clkdiv/ratediv = 0x%02x/0x%02x)\n",
   1188		 state->dcur.symbol_rate,
   1189		 state->dcur.clkdiv, state->dcur.ratediv);
   1190	dev_dbg(&state->i2c->dev,
   1191		"FEC         = %d (mask/val = 0x%02x/0x%02x)\n",
   1192		state->dcur.fec, state->dcur.fec_mask, state->dcur.fec_val);
   1193	dev_dbg(&state->i2c->dev,
   1194		"Inversion   = %d (val = 0x%02x)\n",
   1195		state->dcur.inversion, state->dcur.inversion_val);
   1196
   1197	/* Flag that clock needs to be set after tune */
   1198	state->need_clock_set = 1;
   1199
   1200	/* Tune in */
   1201	cmd.id = CMD_TUNEREQUEST;
   1202	cmd.len = 15;
   1203	cmd.arg[0] = 0;
   1204	cmd.arg[1]  = (state->dcur.frequency & 0xff0000) >> 16;
   1205	cmd.arg[2]  = (state->dcur.frequency & 0x00ff00) >> 8;
   1206	cmd.arg[3]  = (state->dcur.frequency & 0x0000ff);
   1207	cmd.arg[4]  = ((state->dcur.symbol_rate / 1000) & 0xff00) >> 8;
   1208	cmd.arg[5]  = ((state->dcur.symbol_rate / 1000) & 0x00ff);
   1209	cmd.arg[6]  = state->dcur.inversion;
   1210	cmd.arg[7]  = state->dcur.fec_val | state->dcur.pilot_val;
   1211	cmd.arg[8]  = CX24120_SEARCH_RANGE_KHZ >> 8;
   1212	cmd.arg[9]  = CX24120_SEARCH_RANGE_KHZ & 0xff;
   1213	cmd.arg[10] = 0;		/* maybe rolloff? */
   1214	cmd.arg[11] = state->dcur.fec_mask;
   1215	cmd.arg[12] = state->dcur.ratediv;
   1216	cmd.arg[13] = state->dcur.clkdiv;
   1217	cmd.arg[14] = 0;
   1218
   1219	/* Send tune command */
   1220	ret = cx24120_message_send(state, &cmd);
   1221	if (ret != 0)
   1222		return ret;
   1223
   1224	/* Write symbol rate values */
   1225	ret = cx24120_writereg(state, CX24120_REG_CLKDIV, state->dcur.clkdiv);
   1226	ret = cx24120_readreg(state, CX24120_REG_RATEDIV);
   1227	ret &= 0xfffffff0;
   1228	ret |= state->dcur.ratediv;
   1229	ret = cx24120_writereg(state, CX24120_REG_RATEDIV, ret);
   1230
   1231	return 0;
   1232}
   1233
   1234/* Set vco from config */
   1235static int cx24120_set_vco(struct cx24120_state *state)
   1236{
   1237	struct cx24120_cmd cmd;
   1238	u32 nxtal_khz, vco;
   1239	u64 inv_vco;
   1240	u32 xtal_khz = state->config->xtal_khz;
   1241
   1242	nxtal_khz = xtal_khz * 4;
   1243	vco = nxtal_khz * 10;
   1244	inv_vco = DIV_ROUND_CLOSEST_ULL(0x400000000ULL, vco);
   1245
   1246	dev_dbg(&state->i2c->dev, "xtal=%d, vco=%d, inv_vco=%lld\n",
   1247		xtal_khz, vco, inv_vco);
   1248
   1249	cmd.id = CMD_VCO_SET;
   1250	cmd.len = 12;
   1251	cmd.arg[0] = (vco >> 16) & 0xff;
   1252	cmd.arg[1] = (vco >> 8) & 0xff;
   1253	cmd.arg[2] = vco & 0xff;
   1254	cmd.arg[3] = (inv_vco >> 8) & 0xff;
   1255	cmd.arg[4] = (inv_vco) & 0xff;
   1256	cmd.arg[5] = 0x03;
   1257	cmd.arg[6] = (nxtal_khz >> 8) & 0xff;
   1258	cmd.arg[7] = nxtal_khz & 0xff;
   1259	cmd.arg[8] = 0x06;
   1260	cmd.arg[9] = 0x03;
   1261	cmd.arg[10] = (xtal_khz >> 16) & 0xff;
   1262	cmd.arg[11] = xtal_khz & 0xff;
   1263
   1264	return cx24120_message_send(state, &cmd);
   1265}
   1266
   1267static int cx24120_init(struct dvb_frontend *fe)
   1268{
   1269	const struct firmware *fw;
   1270	struct dtv_frontend_properties *c = &fe->dtv_property_cache;
   1271	struct cx24120_state *state = fe->demodulator_priv;
   1272	struct cx24120_cmd cmd;
   1273	u8 reg;
   1274	int ret, i;
   1275	unsigned char vers[4];
   1276
   1277	if (state->cold_init)
   1278		return 0;
   1279
   1280	/* ???? */
   1281	cx24120_writereg(state, 0xea, 0x00);
   1282	cx24120_test_rom(state);
   1283	reg = cx24120_readreg(state, 0xfb) & 0xfe;
   1284	cx24120_writereg(state, 0xfb, reg);
   1285	reg = cx24120_readreg(state, 0xfc) & 0xfe;
   1286	cx24120_writereg(state, 0xfc, reg);
   1287	cx24120_writereg(state, 0xc3, 0x04);
   1288	cx24120_writereg(state, 0xc4, 0x04);
   1289	cx24120_writereg(state, 0xce, 0x00);
   1290	cx24120_writereg(state, 0xcf, 0x00);
   1291	reg = cx24120_readreg(state, 0xea) & 0xfe;
   1292	cx24120_writereg(state, 0xea, reg);
   1293	cx24120_writereg(state, 0xeb, 0x0c);
   1294	cx24120_writereg(state, 0xec, 0x06);
   1295	cx24120_writereg(state, 0xed, 0x05);
   1296	cx24120_writereg(state, 0xee, 0x03);
   1297	cx24120_writereg(state, 0xef, 0x05);
   1298	cx24120_writereg(state, 0xf3, 0x03);
   1299	cx24120_writereg(state, 0xf4, 0x44);
   1300
   1301	for (i = 0; i < 3; i++) {
   1302		cx24120_writereg(state, 0xf0 + i, 0x04);
   1303		cx24120_writereg(state, 0xe6 + i, 0x02);
   1304	}
   1305
   1306	cx24120_writereg(state, 0xea, (reg | 0x01));
   1307	for (i = 0; i < 6; i += 2) {
   1308		cx24120_writereg(state, 0xc5 + i, 0x00);
   1309		cx24120_writereg(state, 0xc6 + i, 0x00);
   1310	}
   1311
   1312	cx24120_writereg(state, 0xe4, 0x03);
   1313	cx24120_writereg(state, 0xeb, 0x0a);
   1314
   1315	dev_dbg(&state->i2c->dev, "requesting firmware (%s) to download...\n",
   1316		CX24120_FIRMWARE);
   1317
   1318	ret = state->config->request_firmware(fe, &fw, CX24120_FIRMWARE);
   1319	if (ret) {
   1320		err("Could not load firmware (%s): %d\n", CX24120_FIRMWARE,
   1321		    ret);
   1322		return ret;
   1323	}
   1324
   1325	dev_dbg(&state->i2c->dev,
   1326		"Firmware found, size %d bytes (%02x %02x .. %02x %02x)\n",
   1327		(int)fw->size,			/* firmware_size in bytes */
   1328		fw->data[0],			/* fw 1st byte */
   1329		fw->data[1],			/* fw 2d byte */
   1330		fw->data[fw->size - 2],		/* fw before last byte */
   1331		fw->data[fw->size - 1]);	/* fw last byte */
   1332
   1333	cx24120_test_rom(state);
   1334	reg = cx24120_readreg(state, 0xfb) & 0xfe;
   1335	cx24120_writereg(state, 0xfb, reg);
   1336	cx24120_writereg(state, 0xe0, 0x76);
   1337	cx24120_writereg(state, 0xf7, 0x81);
   1338	cx24120_writereg(state, 0xf8, 0x00);
   1339	cx24120_writereg(state, 0xf9, 0x00);
   1340	cx24120_writeregs(state, 0xfa, fw->data, (fw->size - 1), 0x00);
   1341	cx24120_writereg(state, 0xf7, 0xc0);
   1342	cx24120_writereg(state, 0xe0, 0x00);
   1343	reg = (fw->size - 2) & 0x00ff;
   1344	cx24120_writereg(state, 0xf8, reg);
   1345	reg = ((fw->size - 2) >> 8) & 0x00ff;
   1346	cx24120_writereg(state, 0xf9, reg);
   1347	cx24120_writereg(state, 0xf7, 0x00);
   1348	cx24120_writereg(state, 0xdc, 0x00);
   1349	cx24120_writereg(state, 0xdc, 0x07);
   1350	msleep(500);
   1351
   1352	/* Check final byte matches final byte of firmware */
   1353	reg = cx24120_readreg(state, 0xe1);
   1354	if (reg == fw->data[fw->size - 1]) {
   1355		dev_dbg(&state->i2c->dev, "Firmware uploaded successfully\n");
   1356		ret = 0;
   1357	} else {
   1358		err("Firmware upload failed. Last byte returned=0x%x\n", ret);
   1359		ret = -EREMOTEIO;
   1360	}
   1361	cx24120_writereg(state, 0xdc, 0x00);
   1362	release_firmware(fw);
   1363	if (ret != 0)
   1364		return ret;
   1365
   1366	/* Start tuner */
   1367	cmd.id = CMD_START_TUNER;
   1368	cmd.len = 3;
   1369	cmd.arg[0] = 0x00;
   1370	cmd.arg[1] = 0x00;
   1371	cmd.arg[2] = 0x00;
   1372
   1373	if (cx24120_message_send(state, &cmd) != 0) {
   1374		err("Error tuner start! :(\n");
   1375		return -EREMOTEIO;
   1376	}
   1377
   1378	/* Set VCO */
   1379	ret = cx24120_set_vco(state);
   1380	if (ret != 0) {
   1381		err("Error set VCO! :(\n");
   1382		return ret;
   1383	}
   1384
   1385	/* set bandwidth */
   1386	cmd.id = CMD_BANDWIDTH;
   1387	cmd.len = 12;
   1388	cmd.arg[0] = 0x00;
   1389	cmd.arg[1] = 0x00;
   1390	cmd.arg[2] = 0x00;
   1391	cmd.arg[3] = 0x00;
   1392	cmd.arg[4] = 0x05;
   1393	cmd.arg[5] = 0x02;
   1394	cmd.arg[6] = 0x02;
   1395	cmd.arg[7] = 0x00;
   1396	cmd.arg[8] = 0x05;
   1397	cmd.arg[9] = 0x02;
   1398	cmd.arg[10] = 0x02;
   1399	cmd.arg[11] = 0x00;
   1400
   1401	if (cx24120_message_send(state, &cmd)) {
   1402		err("Error set bandwidth!\n");
   1403		return -EREMOTEIO;
   1404	}
   1405
   1406	reg = cx24120_readreg(state, 0xba);
   1407	if (reg > 3) {
   1408		dev_dbg(&state->i2c->dev, "Reset-readreg 0xba: %x\n", ret);
   1409		err("Error initialising tuner!\n");
   1410		return -EREMOTEIO;
   1411	}
   1412
   1413	dev_dbg(&state->i2c->dev, "Tuner initialised correctly.\n");
   1414
   1415	/* Initialise mpeg outputs */
   1416	cx24120_writereg(state, 0xeb, 0x0a);
   1417	if (cx24120_msg_mpeg_output_global_config(state, 0) ||
   1418	    cx24120_msg_mpeg_output_config(state, 0) ||
   1419	    cx24120_msg_mpeg_output_config(state, 1) ||
   1420	    cx24120_msg_mpeg_output_config(state, 2)) {
   1421		err("Error initialising mpeg output. :(\n");
   1422		return -EREMOTEIO;
   1423	}
   1424
   1425	/* Set size of BER window */
   1426	cmd.id = CMD_BER_CTRL;
   1427	cmd.len = 3;
   1428	cmd.arg[0] = 0x00;
   1429	cmd.arg[1] = CX24120_BER_WINDOW;
   1430	cmd.arg[2] = CX24120_BER_WINDOW;
   1431	if (cx24120_message_send(state, &cmd)) {
   1432		err("Error setting ber window\n");
   1433		return -EREMOTEIO;
   1434	}
   1435
   1436	/* Firmware CMD 35: Get firmware version */
   1437	cmd.id = CMD_FWVERSION;
   1438	cmd.len = 1;
   1439	for (i = 0; i < 4; i++) {
   1440		cmd.arg[0] = i;
   1441		ret = cx24120_message_send(state, &cmd);
   1442		if (ret != 0)
   1443			return ret;
   1444		vers[i] = cx24120_readreg(state, CX24120_REG_MAILBOX);
   1445	}
   1446	info("FW version %i.%i.%i.%i\n", vers[0], vers[1], vers[2], vers[3]);
   1447
   1448	/* init stats here in order signal app which stats are supported */
   1449	c->strength.len = 1;
   1450	c->strength.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
   1451	c->cnr.len = 1;
   1452	c->cnr.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
   1453	c->post_bit_error.len = 1;
   1454	c->post_bit_error.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
   1455	c->post_bit_count.len = 1;
   1456	c->post_bit_count.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
   1457	c->block_error.len = 1;
   1458	c->block_error.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
   1459	c->block_count.len = 1;
   1460	c->block_count.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
   1461
   1462	state->cold_init = 1;
   1463
   1464	return 0;
   1465}
   1466
   1467static int cx24120_tune(struct dvb_frontend *fe, bool re_tune,
   1468			unsigned int mode_flags, unsigned int *delay,
   1469			enum fe_status *status)
   1470{
   1471	struct cx24120_state *state = fe->demodulator_priv;
   1472	int ret;
   1473
   1474	dev_dbg(&state->i2c->dev, "(%d)\n", re_tune);
   1475
   1476	/* TODO: Do we need to set delay? */
   1477
   1478	if (re_tune) {
   1479		ret = cx24120_set_frontend(fe);
   1480		if (ret)
   1481			return ret;
   1482	}
   1483
   1484	return cx24120_read_status(fe, status);
   1485}
   1486
   1487static enum dvbfe_algo cx24120_get_algo(struct dvb_frontend *fe)
   1488{
   1489	return DVBFE_ALGO_HW;
   1490}
   1491
   1492static int cx24120_sleep(struct dvb_frontend *fe)
   1493{
   1494	return 0;
   1495}
   1496
   1497static int cx24120_get_frontend(struct dvb_frontend *fe,
   1498				struct dtv_frontend_properties *c)
   1499{
   1500	struct cx24120_state *state = fe->demodulator_priv;
   1501	u8 freq1, freq2, freq3;
   1502	int status;
   1503
   1504	dev_dbg(&state->i2c->dev, "\n");
   1505
   1506	/* don't return empty data if we're not tuned in */
   1507	status = cx24120_readreg(state, CX24120_REG_STATUS);
   1508	if (!(status & CX24120_HAS_LOCK))
   1509		return 0;
   1510
   1511	/* Get frequency */
   1512	freq1 = cx24120_readreg(state, CX24120_REG_FREQ1);
   1513	freq2 = cx24120_readreg(state, CX24120_REG_FREQ2);
   1514	freq3 = cx24120_readreg(state, CX24120_REG_FREQ3);
   1515	c->frequency = (freq3 << 16) | (freq2 << 8) | freq1;
   1516	dev_dbg(&state->i2c->dev, "frequency = %d\n", c->frequency);
   1517
   1518	/* Get modulation, fec, pilot */
   1519	cx24120_get_fec(fe);
   1520
   1521	return 0;
   1522}
   1523
   1524static void cx24120_release(struct dvb_frontend *fe)
   1525{
   1526	struct cx24120_state *state = fe->demodulator_priv;
   1527
   1528	dev_dbg(&state->i2c->dev, "Clear state structure\n");
   1529	kfree(state);
   1530}
   1531
   1532static int cx24120_read_ucblocks(struct dvb_frontend *fe, u32 *ucblocks)
   1533{
   1534	struct cx24120_state *state = fe->demodulator_priv;
   1535	struct dtv_frontend_properties *c = &fe->dtv_property_cache;
   1536
   1537	if (c->block_error.stat[0].scale != FE_SCALE_COUNTER) {
   1538		*ucblocks = 0;
   1539		return 0;
   1540	}
   1541
   1542	*ucblocks = c->block_error.stat[0].uvalue - state->ucb_offset;
   1543
   1544	return 0;
   1545}
   1546
   1547static const struct dvb_frontend_ops cx24120_ops = {
   1548	.delsys = { SYS_DVBS, SYS_DVBS2 },
   1549	.info = {
   1550		.name = "Conexant CX24120/CX24118",
   1551		.frequency_min_hz =  950 * MHz,
   1552		.frequency_max_hz = 2150 * MHz,
   1553		.frequency_stepsize_hz = 1011 * kHz,
   1554		.frequency_tolerance_hz = 5 * MHz,
   1555		.symbol_rate_min = 1000000,
   1556		.symbol_rate_max = 45000000,
   1557		.caps =	FE_CAN_INVERSION_AUTO |
   1558			FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4 |
   1559			FE_CAN_FEC_4_5 | FE_CAN_FEC_5_6 | FE_CAN_FEC_6_7 |
   1560			FE_CAN_FEC_7_8 | FE_CAN_FEC_AUTO |
   1561			FE_CAN_2G_MODULATION |
   1562			FE_CAN_QPSK | FE_CAN_RECOVER
   1563	},
   1564	.release =			cx24120_release,
   1565
   1566	.init =				cx24120_init,
   1567	.sleep =			cx24120_sleep,
   1568
   1569	.tune =				cx24120_tune,
   1570	.get_frontend_algo =		cx24120_get_algo,
   1571	.set_frontend =			cx24120_set_frontend,
   1572
   1573	.get_frontend =			cx24120_get_frontend,
   1574	.read_status =			cx24120_read_status,
   1575	.read_ber =			cx24120_read_ber,
   1576	.read_signal_strength =		cx24120_read_signal_strength,
   1577	.read_snr =			cx24120_read_snr,
   1578	.read_ucblocks =		cx24120_read_ucblocks,
   1579
   1580	.diseqc_send_master_cmd =	cx24120_send_diseqc_msg,
   1581
   1582	.diseqc_send_burst =		cx24120_diseqc_send_burst,
   1583	.set_tone =			cx24120_set_tone,
   1584	.set_voltage =			cx24120_set_voltage,
   1585};
   1586
   1587MODULE_DESCRIPTION("DVB Frontend module for Conexant CX24120/CX24118 hardware");
   1588MODULE_AUTHOR("Jemma Denson");
   1589MODULE_LICENSE("GPL");