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

cx24123.c (29154B)


      1// SPDX-License-Identifier: GPL-2.0-or-later
      2/*
      3 *   Conexant cx24123/cx24109 - DVB QPSK Satellite demod/tuner driver
      4 *
      5 *   Copyright (C) 2005 Steven Toth <stoth@linuxtv.org>
      6 *
      7 *   Support for KWorld DVB-S 100 by Vadim Catana <skystar@moldova.cc>
      8 *
      9 *   Support for CX24123/CX24113-NIM by Patrick Boettcher <pb@linuxtv.org>
     10 */
     11
     12#include <linux/slab.h>
     13#include <linux/kernel.h>
     14#include <linux/module.h>
     15#include <linux/init.h>
     16#include <asm/div64.h>
     17
     18#include <media/dvb_frontend.h>
     19#include "cx24123.h"
     20
     21#define XTAL 10111000
     22
     23static int force_band;
     24module_param(force_band, int, 0644);
     25MODULE_PARM_DESC(force_band, "Force a specific band select "\
     26	"(1-9, default:off).");
     27
     28static int debug;
     29module_param(debug, int, 0644);
     30MODULE_PARM_DESC(debug, "Activates frontend debugging (default:0)");
     31
     32#define info(args...) do { printk(KERN_INFO "CX24123: " args); } while (0)
     33#define err(args...)  do { printk(KERN_ERR  "CX24123: " args); } while (0)
     34
     35#define dprintk(args...) \
     36	do { \
     37		if (debug) { \
     38			printk(KERN_DEBUG "CX24123: %s: ", __func__); \
     39			printk(args); \
     40		} \
     41	} while (0)
     42
     43struct cx24123_state {
     44	struct i2c_adapter *i2c;
     45	const struct cx24123_config *config;
     46
     47	struct dvb_frontend frontend;
     48
     49	/* Some PLL specifics for tuning */
     50	u32 VCAarg;
     51	u32 VGAarg;
     52	u32 bandselectarg;
     53	u32 pllarg;
     54	u32 FILTune;
     55
     56	struct i2c_adapter tuner_i2c_adapter;
     57
     58	u8 demod_rev;
     59
     60	/* The Demod/Tuner can't easily provide these, we cache them */
     61	u32 currentfreq;
     62	u32 currentsymbolrate;
     63};
     64
     65/* Various tuner defaults need to be established for a given symbol rate Sps */
     66static struct cx24123_AGC_val {
     67	u32 symbolrate_low;
     68	u32 symbolrate_high;
     69	u32 VCAprogdata;
     70	u32 VGAprogdata;
     71	u32 FILTune;
     72} cx24123_AGC_vals[] =
     73{
     74	{
     75		.symbolrate_low		= 1000000,
     76		.symbolrate_high	= 4999999,
     77		/* the specs recommend other values for VGA offsets,
     78		   but tests show they are wrong */
     79		.VGAprogdata		= (1 << 19) | (0x180 << 9) | 0x1e0,
     80		.VCAprogdata		= (2 << 19) | (0x07 << 9) | 0x07,
     81		.FILTune		= 0x27f /* 0.41 V */
     82	},
     83	{
     84		.symbolrate_low		=  5000000,
     85		.symbolrate_high	= 14999999,
     86		.VGAprogdata		= (1 << 19) | (0x180 << 9) | 0x1e0,
     87		.VCAprogdata		= (2 << 19) | (0x07 << 9) | 0x1f,
     88		.FILTune		= 0x317 /* 0.90 V */
     89	},
     90	{
     91		.symbolrate_low		= 15000000,
     92		.symbolrate_high	= 45000000,
     93		.VGAprogdata		= (1 << 19) | (0x100 << 9) | 0x180,
     94		.VCAprogdata		= (2 << 19) | (0x07 << 9) | 0x3f,
     95		.FILTune		= 0x145 /* 2.70 V */
     96	},
     97};
     98
     99/*
    100 * Various tuner defaults need to be established for a given frequency kHz.
    101 * fixme: The bounds on the bands do not match the doc in real life.
    102 * fixme: Some of them have been moved, other might need adjustment.
    103 */
    104static struct cx24123_bandselect_val {
    105	u32 freq_low;
    106	u32 freq_high;
    107	u32 VCOdivider;
    108	u32 progdata;
    109} cx24123_bandselect_vals[] =
    110{
    111	/* band 1 */
    112	{
    113		.freq_low	= 950000,
    114		.freq_high	= 1074999,
    115		.VCOdivider	= 4,
    116		.progdata	= (0 << 19) | (0 << 9) | 0x40,
    117	},
    118
    119	/* band 2 */
    120	{
    121		.freq_low	= 1075000,
    122		.freq_high	= 1177999,
    123		.VCOdivider	= 4,
    124		.progdata	= (0 << 19) | (0 << 9) | 0x80,
    125	},
    126
    127	/* band 3 */
    128	{
    129		.freq_low	= 1178000,
    130		.freq_high	= 1295999,
    131		.VCOdivider	= 2,
    132		.progdata	= (0 << 19) | (1 << 9) | 0x01,
    133	},
    134
    135	/* band 4 */
    136	{
    137		.freq_low	= 1296000,
    138		.freq_high	= 1431999,
    139		.VCOdivider	= 2,
    140		.progdata	= (0 << 19) | (1 << 9) | 0x02,
    141	},
    142
    143	/* band 5 */
    144	{
    145		.freq_low	= 1432000,
    146		.freq_high	= 1575999,
    147		.VCOdivider	= 2,
    148		.progdata	= (0 << 19) | (1 << 9) | 0x04,
    149	},
    150
    151	/* band 6 */
    152	{
    153		.freq_low	= 1576000,
    154		.freq_high	= 1717999,
    155		.VCOdivider	= 2,
    156		.progdata	= (0 << 19) | (1 << 9) | 0x08,
    157	},
    158
    159	/* band 7 */
    160	{
    161		.freq_low	= 1718000,
    162		.freq_high	= 1855999,
    163		.VCOdivider	= 2,
    164		.progdata	= (0 << 19) | (1 << 9) | 0x10,
    165	},
    166
    167	/* band 8 */
    168	{
    169		.freq_low	= 1856000,
    170		.freq_high	= 2035999,
    171		.VCOdivider	= 2,
    172		.progdata	= (0 << 19) | (1 << 9) | 0x20,
    173	},
    174
    175	/* band 9 */
    176	{
    177		.freq_low	= 2036000,
    178		.freq_high	= 2150000,
    179		.VCOdivider	= 2,
    180		.progdata	= (0 << 19) | (1 << 9) | 0x40,
    181	},
    182};
    183
    184static struct {
    185	u8 reg;
    186	u8 data;
    187} cx24123_regdata[] =
    188{
    189	{0x00, 0x03}, /* Reset system */
    190	{0x00, 0x00}, /* Clear reset */
    191	{0x03, 0x07}, /* QPSK, DVB, Auto Acquisition (default) */
    192	{0x04, 0x10}, /* MPEG */
    193	{0x05, 0x04}, /* MPEG */
    194	{0x06, 0x31}, /* MPEG (default) */
    195	{0x0b, 0x00}, /* Freq search start point (default) */
    196	{0x0c, 0x00}, /* Demodulator sample gain (default) */
    197	{0x0d, 0x7f}, /* Force driver to shift until the maximum (+-10 MHz) */
    198	{0x0e, 0x03}, /* Default non-inverted, FEC 3/4 (default) */
    199	{0x0f, 0xfe}, /* FEC search mask (all supported codes) */
    200	{0x10, 0x01}, /* Default search inversion, no repeat (default) */
    201	{0x16, 0x00}, /* Enable reading of frequency */
    202	{0x17, 0x01}, /* Enable EsNO Ready Counter */
    203	{0x1c, 0x80}, /* Enable error counter */
    204	{0x20, 0x00}, /* Tuner burst clock rate = 500KHz */
    205	{0x21, 0x15}, /* Tuner burst mode, word length = 0x15 */
    206	{0x28, 0x00}, /* Enable FILTERV with positive pol., DiSEqC 2.x off */
    207	{0x29, 0x00}, /* DiSEqC LNB_DC off */
    208	{0x2a, 0xb0}, /* DiSEqC Parameters (default) */
    209	{0x2b, 0x73}, /* DiSEqC Tone Frequency (default) */
    210	{0x2c, 0x00}, /* DiSEqC Message (0x2c - 0x31) */
    211	{0x2d, 0x00},
    212	{0x2e, 0x00},
    213	{0x2f, 0x00},
    214	{0x30, 0x00},
    215	{0x31, 0x00},
    216	{0x32, 0x8c}, /* DiSEqC Parameters (default) */
    217	{0x33, 0x00}, /* Interrupts off (0x33 - 0x34) */
    218	{0x34, 0x00},
    219	{0x35, 0x03}, /* DiSEqC Tone Amplitude (default) */
    220	{0x36, 0x02}, /* DiSEqC Parameters (default) */
    221	{0x37, 0x3a}, /* DiSEqC Parameters (default) */
    222	{0x3a, 0x00}, /* Enable AGC accumulator (for signal strength) */
    223	{0x44, 0x00}, /* Constellation (default) */
    224	{0x45, 0x00}, /* Symbol count (default) */
    225	{0x46, 0x0d}, /* Symbol rate estimator on (default) */
    226	{0x56, 0xc1}, /* Error Counter = Viterbi BER */
    227	{0x57, 0xff}, /* Error Counter Window (default) */
    228	{0x5c, 0x20}, /* Acquisition AFC Expiration window (default is 0x10) */
    229	{0x67, 0x83}, /* Non-DCII symbol clock */
    230};
    231
    232static int cx24123_i2c_writereg(struct cx24123_state *state,
    233	u8 i2c_addr, int reg, int data)
    234{
    235	u8 buf[] = { reg, data };
    236	struct i2c_msg msg = {
    237		.addr = i2c_addr, .flags = 0, .buf = buf, .len = 2
    238	};
    239	int err;
    240
    241	/* printk(KERN_DEBUG "wr(%02x): %02x %02x\n", i2c_addr, reg, data); */
    242
    243	err = i2c_transfer(state->i2c, &msg, 1);
    244	if (err != 1) {
    245		printk("%s: writereg error(err == %i, reg == 0x%02x, data == 0x%02x)\n",
    246		       __func__, err, reg, data);
    247		return err;
    248	}
    249
    250	return 0;
    251}
    252
    253static int cx24123_i2c_readreg(struct cx24123_state *state, u8 i2c_addr, u8 reg)
    254{
    255	int ret;
    256	u8 b = 0;
    257	struct i2c_msg msg[] = {
    258		{ .addr = i2c_addr, .flags = 0, .buf = &reg, .len = 1 },
    259		{ .addr = i2c_addr, .flags = I2C_M_RD, .buf = &b, .len = 1 }
    260	};
    261
    262	ret = i2c_transfer(state->i2c, msg, 2);
    263
    264	if (ret != 2) {
    265		err("%s: reg=0x%x (error=%d)\n", __func__, reg, ret);
    266		return ret;
    267	}
    268
    269	/* printk(KERN_DEBUG "rd(%02x): %02x %02x\n", i2c_addr, reg, b); */
    270
    271	return b;
    272}
    273
    274#define cx24123_readreg(state, reg) \
    275	cx24123_i2c_readreg(state, state->config->demod_address, reg)
    276#define cx24123_writereg(state, reg, val) \
    277	cx24123_i2c_writereg(state, state->config->demod_address, reg, val)
    278
    279static int cx24123_set_inversion(struct cx24123_state *state,
    280				 enum fe_spectral_inversion inversion)
    281{
    282	u8 nom_reg = cx24123_readreg(state, 0x0e);
    283	u8 auto_reg = cx24123_readreg(state, 0x10);
    284
    285	switch (inversion) {
    286	case INVERSION_OFF:
    287		dprintk("inversion off\n");
    288		cx24123_writereg(state, 0x0e, nom_reg & ~0x80);
    289		cx24123_writereg(state, 0x10, auto_reg | 0x80);
    290		break;
    291	case INVERSION_ON:
    292		dprintk("inversion on\n");
    293		cx24123_writereg(state, 0x0e, nom_reg | 0x80);
    294		cx24123_writereg(state, 0x10, auto_reg | 0x80);
    295		break;
    296	case INVERSION_AUTO:
    297		dprintk("inversion auto\n");
    298		cx24123_writereg(state, 0x10, auto_reg & ~0x80);
    299		break;
    300	default:
    301		return -EINVAL;
    302	}
    303
    304	return 0;
    305}
    306
    307static int cx24123_get_inversion(struct cx24123_state *state,
    308				 enum fe_spectral_inversion *inversion)
    309{
    310	u8 val;
    311
    312	val = cx24123_readreg(state, 0x1b) >> 7;
    313
    314	if (val == 0) {
    315		dprintk("read inversion off\n");
    316		*inversion = INVERSION_OFF;
    317	} else {
    318		dprintk("read inversion on\n");
    319		*inversion = INVERSION_ON;
    320	}
    321
    322	return 0;
    323}
    324
    325static int cx24123_set_fec(struct cx24123_state *state, enum fe_code_rate fec)
    326{
    327	u8 nom_reg = cx24123_readreg(state, 0x0e) & ~0x07;
    328
    329	if (((int)fec < FEC_NONE) || (fec > FEC_AUTO))
    330		fec = FEC_AUTO;
    331
    332	/* Set the soft decision threshold */
    333	if (fec == FEC_1_2)
    334		cx24123_writereg(state, 0x43,
    335			cx24123_readreg(state, 0x43) | 0x01);
    336	else
    337		cx24123_writereg(state, 0x43,
    338			cx24123_readreg(state, 0x43) & ~0x01);
    339
    340	switch (fec) {
    341	case FEC_1_2:
    342		dprintk("set FEC to 1/2\n");
    343		cx24123_writereg(state, 0x0e, nom_reg | 0x01);
    344		cx24123_writereg(state, 0x0f, 0x02);
    345		break;
    346	case FEC_2_3:
    347		dprintk("set FEC to 2/3\n");
    348		cx24123_writereg(state, 0x0e, nom_reg | 0x02);
    349		cx24123_writereg(state, 0x0f, 0x04);
    350		break;
    351	case FEC_3_4:
    352		dprintk("set FEC to 3/4\n");
    353		cx24123_writereg(state, 0x0e, nom_reg | 0x03);
    354		cx24123_writereg(state, 0x0f, 0x08);
    355		break;
    356	case FEC_4_5:
    357		dprintk("set FEC to 4/5\n");
    358		cx24123_writereg(state, 0x0e, nom_reg | 0x04);
    359		cx24123_writereg(state, 0x0f, 0x10);
    360		break;
    361	case FEC_5_6:
    362		dprintk("set FEC to 5/6\n");
    363		cx24123_writereg(state, 0x0e, nom_reg | 0x05);
    364		cx24123_writereg(state, 0x0f, 0x20);
    365		break;
    366	case FEC_6_7:
    367		dprintk("set FEC to 6/7\n");
    368		cx24123_writereg(state, 0x0e, nom_reg | 0x06);
    369		cx24123_writereg(state, 0x0f, 0x40);
    370		break;
    371	case FEC_7_8:
    372		dprintk("set FEC to 7/8\n");
    373		cx24123_writereg(state, 0x0e, nom_reg | 0x07);
    374		cx24123_writereg(state, 0x0f, 0x80);
    375		break;
    376	case FEC_AUTO:
    377		dprintk("set FEC to auto\n");
    378		cx24123_writereg(state, 0x0f, 0xfe);
    379		break;
    380	default:
    381		return -EOPNOTSUPP;
    382	}
    383
    384	return 0;
    385}
    386
    387static int cx24123_get_fec(struct cx24123_state *state, enum fe_code_rate *fec)
    388{
    389	int ret;
    390
    391	ret = cx24123_readreg(state, 0x1b);
    392	if (ret < 0)
    393		return ret;
    394	ret = ret & 0x07;
    395
    396	switch (ret) {
    397	case 1:
    398		*fec = FEC_1_2;
    399		break;
    400	case 2:
    401		*fec = FEC_2_3;
    402		break;
    403	case 3:
    404		*fec = FEC_3_4;
    405		break;
    406	case 4:
    407		*fec = FEC_4_5;
    408		break;
    409	case 5:
    410		*fec = FEC_5_6;
    411		break;
    412	case 6:
    413		*fec = FEC_6_7;
    414		break;
    415	case 7:
    416		*fec = FEC_7_8;
    417		break;
    418	default:
    419		/* this can happen when there's no lock */
    420		*fec = FEC_NONE;
    421	}
    422
    423	return 0;
    424}
    425
    426/* Approximation of closest integer of log2(a/b). It actually gives the
    427   lowest integer i such that 2^i >= round(a/b) */
    428static u32 cx24123_int_log2(u32 a, u32 b)
    429{
    430	u32 exp, nearest = 0;
    431	u32 div = a / b;
    432	if (a % b >= b / 2)
    433		++div;
    434	if (div < (1UL << 31)) {
    435		for (exp = 1; div > exp; nearest++)
    436			exp += exp;
    437	}
    438	return nearest;
    439}
    440
    441static int cx24123_set_symbolrate(struct cx24123_state *state, u32 srate)
    442{
    443	u64 tmp;
    444	u32 sample_rate, ratio, sample_gain;
    445	u8 pll_mult;
    446
    447	/*  check if symbol rate is within limits */
    448	if ((srate > state->frontend.ops.info.symbol_rate_max) ||
    449	    (srate < state->frontend.ops.info.symbol_rate_min))
    450		return -EOPNOTSUPP;
    451
    452	/* choose the sampling rate high enough for the required operation,
    453	   while optimizing the power consumed by the demodulator */
    454	if (srate < (XTAL*2)/2)
    455		pll_mult = 2;
    456	else if (srate < (XTAL*3)/2)
    457		pll_mult = 3;
    458	else if (srate < (XTAL*4)/2)
    459		pll_mult = 4;
    460	else if (srate < (XTAL*5)/2)
    461		pll_mult = 5;
    462	else if (srate < (XTAL*6)/2)
    463		pll_mult = 6;
    464	else if (srate < (XTAL*7)/2)
    465		pll_mult = 7;
    466	else if (srate < (XTAL*8)/2)
    467		pll_mult = 8;
    468	else
    469		pll_mult = 9;
    470
    471
    472	sample_rate = pll_mult * XTAL;
    473
    474	/* SYSSymbolRate[21:0] = (srate << 23) / sample_rate */
    475
    476	tmp = ((u64)srate) << 23;
    477	do_div(tmp, sample_rate);
    478	ratio = (u32) tmp;
    479
    480	cx24123_writereg(state, 0x01, pll_mult * 6);
    481
    482	cx24123_writereg(state, 0x08, (ratio >> 16) & 0x3f);
    483	cx24123_writereg(state, 0x09, (ratio >> 8) & 0xff);
    484	cx24123_writereg(state, 0x0a, ratio & 0xff);
    485
    486	/* also set the demodulator sample gain */
    487	sample_gain = cx24123_int_log2(sample_rate, srate);
    488	tmp = cx24123_readreg(state, 0x0c) & ~0xe0;
    489	cx24123_writereg(state, 0x0c, tmp | sample_gain << 5);
    490
    491	dprintk("srate=%d, ratio=0x%08x, sample_rate=%i sample_gain=%d\n",
    492		srate, ratio, sample_rate, sample_gain);
    493
    494	return 0;
    495}
    496
    497/*
    498 * Based on the required frequency and symbolrate, the tuner AGC has
    499 * to be configured and the correct band selected.
    500 * Calculate those values.
    501 */
    502static int cx24123_pll_calculate(struct dvb_frontend *fe)
    503{
    504	struct dtv_frontend_properties *p = &fe->dtv_property_cache;
    505	struct cx24123_state *state = fe->demodulator_priv;
    506	u32 ndiv = 0, adiv = 0, vco_div = 0;
    507	int i = 0;
    508	int pump = 2;
    509	int band = 0;
    510	int num_bands = ARRAY_SIZE(cx24123_bandselect_vals);
    511	struct cx24123_bandselect_val *bsv = NULL;
    512	struct cx24123_AGC_val *agcv = NULL;
    513
    514	/* Defaults for low freq, low rate */
    515	state->VCAarg = cx24123_AGC_vals[0].VCAprogdata;
    516	state->VGAarg = cx24123_AGC_vals[0].VGAprogdata;
    517	state->bandselectarg = cx24123_bandselect_vals[0].progdata;
    518	vco_div = cx24123_bandselect_vals[0].VCOdivider;
    519
    520	/* For the given symbol rate, determine the VCA, VGA and
    521	 * FILTUNE programming bits */
    522	for (i = 0; i < ARRAY_SIZE(cx24123_AGC_vals); i++) {
    523		agcv = &cx24123_AGC_vals[i];
    524		if ((agcv->symbolrate_low <= p->symbol_rate) &&
    525		    (agcv->symbolrate_high >= p->symbol_rate)) {
    526			state->VCAarg = agcv->VCAprogdata;
    527			state->VGAarg = agcv->VGAprogdata;
    528			state->FILTune = agcv->FILTune;
    529		}
    530	}
    531
    532	/* determine the band to use */
    533	if (force_band < 1 || force_band > num_bands) {
    534		for (i = 0; i < num_bands; i++) {
    535			bsv = &cx24123_bandselect_vals[i];
    536			if ((bsv->freq_low <= p->frequency) &&
    537				(bsv->freq_high >= p->frequency))
    538				band = i;
    539		}
    540	} else
    541		band = force_band - 1;
    542
    543	state->bandselectarg = cx24123_bandselect_vals[band].progdata;
    544	vco_div = cx24123_bandselect_vals[band].VCOdivider;
    545
    546	/* determine the charge pump current */
    547	if (p->frequency < (cx24123_bandselect_vals[band].freq_low +
    548		cx24123_bandselect_vals[band].freq_high) / 2)
    549		pump = 0x01;
    550	else
    551		pump = 0x02;
    552
    553	/* Determine the N/A dividers for the requested lband freq (in kHz). */
    554	/* Note: the reference divider R=10, frequency is in KHz,
    555	 * XTAL is in Hz */
    556	ndiv = (((p->frequency * vco_div * 10) /
    557		(2 * XTAL / 1000)) / 32) & 0x1ff;
    558	adiv = (((p->frequency * vco_div * 10) /
    559		(2 * XTAL / 1000)) % 32) & 0x1f;
    560
    561	if (adiv == 0 && ndiv > 0)
    562		ndiv--;
    563
    564	/* control bits 11, refdiv 11, charge pump polarity 1,
    565	 * charge pump current, ndiv, adiv */
    566	state->pllarg = (3 << 19) | (3 << 17) | (1 << 16) |
    567		(pump << 14) | (ndiv << 5) | adiv;
    568
    569	return 0;
    570}
    571
    572/*
    573 * Tuner data is 21 bits long, must be left-aligned in data.
    574 * Tuner cx24109 is written through a dedicated 3wire interface
    575 * on the demod chip.
    576 */
    577static int cx24123_pll_writereg(struct dvb_frontend *fe, u32 data)
    578{
    579	struct cx24123_state *state = fe->demodulator_priv;
    580	unsigned long timeout;
    581
    582	dprintk("pll writereg called, data=0x%08x\n", data);
    583
    584	/* align the 21 bytes into to bit23 boundary */
    585	data = data << 3;
    586
    587	/* Reset the demod pll word length to 0x15 bits */
    588	cx24123_writereg(state, 0x21, 0x15);
    589
    590	/* write the msb 8 bits, wait for the send to be completed */
    591	timeout = jiffies + msecs_to_jiffies(40);
    592	cx24123_writereg(state, 0x22, (data >> 16) & 0xff);
    593	while ((cx24123_readreg(state, 0x20) & 0x40) == 0) {
    594		if (time_after(jiffies, timeout)) {
    595			err("%s:  demodulator is not responding, "\
    596				"possibly hung, aborting.\n", __func__);
    597			return -EREMOTEIO;
    598		}
    599		msleep(10);
    600	}
    601
    602	/* send another 8 bytes, wait for the send to be completed */
    603	timeout = jiffies + msecs_to_jiffies(40);
    604	cx24123_writereg(state, 0x22, (data >> 8) & 0xff);
    605	while ((cx24123_readreg(state, 0x20) & 0x40) == 0) {
    606		if (time_after(jiffies, timeout)) {
    607			err("%s:  demodulator is not responding, "\
    608				"possibly hung, aborting.\n", __func__);
    609			return -EREMOTEIO;
    610		}
    611		msleep(10);
    612	}
    613
    614	/* send the lower 5 bits of this byte, padded with 3 LBB,
    615	 * wait for the send to be completed */
    616	timeout = jiffies + msecs_to_jiffies(40);
    617	cx24123_writereg(state, 0x22, (data) & 0xff);
    618	while ((cx24123_readreg(state, 0x20) & 0x80)) {
    619		if (time_after(jiffies, timeout)) {
    620			err("%s:  demodulator is not responding," \
    621				"possibly hung, aborting.\n", __func__);
    622			return -EREMOTEIO;
    623		}
    624		msleep(10);
    625	}
    626
    627	/* Trigger the demod to configure the tuner */
    628	cx24123_writereg(state, 0x20, cx24123_readreg(state, 0x20) | 2);
    629	cx24123_writereg(state, 0x20, cx24123_readreg(state, 0x20) & 0xfd);
    630
    631	return 0;
    632}
    633
    634static int cx24123_pll_tune(struct dvb_frontend *fe)
    635{
    636	struct dtv_frontend_properties *p = &fe->dtv_property_cache;
    637	struct cx24123_state *state = fe->demodulator_priv;
    638	u8 val;
    639
    640	dprintk("frequency=%i\n", p->frequency);
    641
    642	if (cx24123_pll_calculate(fe) != 0) {
    643		err("%s: cx24123_pll_calculate failed\n", __func__);
    644		return -EINVAL;
    645	}
    646
    647	/* Write the new VCO/VGA */
    648	cx24123_pll_writereg(fe, state->VCAarg);
    649	cx24123_pll_writereg(fe, state->VGAarg);
    650
    651	/* Write the new bandselect and pll args */
    652	cx24123_pll_writereg(fe, state->bandselectarg);
    653	cx24123_pll_writereg(fe, state->pllarg);
    654
    655	/* set the FILTUNE voltage */
    656	val = cx24123_readreg(state, 0x28) & ~0x3;
    657	cx24123_writereg(state, 0x27, state->FILTune >> 2);
    658	cx24123_writereg(state, 0x28, val | (state->FILTune & 0x3));
    659
    660	dprintk("pll tune VCA=%d, band=%d, pll=%d\n", state->VCAarg,
    661			state->bandselectarg, state->pllarg);
    662
    663	return 0;
    664}
    665
    666
    667/*
    668 * 0x23:
    669 *    [7:7] = BTI enabled
    670 *    [6:6] = I2C repeater enabled
    671 *    [5:5] = I2C repeater start
    672 *    [0:0] = BTI start
    673 */
    674
    675/* mode == 1 -> i2c-repeater, 0 -> bti */
    676static int cx24123_repeater_mode(struct cx24123_state *state, u8 mode, u8 start)
    677{
    678	u8 r = cx24123_readreg(state, 0x23) & 0x1e;
    679	if (mode)
    680		r |= (1 << 6) | (start << 5);
    681	else
    682		r |= (1 << 7) | (start);
    683	return cx24123_writereg(state, 0x23, r);
    684}
    685
    686static int cx24123_initfe(struct dvb_frontend *fe)
    687{
    688	struct cx24123_state *state = fe->demodulator_priv;
    689	int i;
    690
    691	dprintk("init frontend\n");
    692
    693	/* Configure the demod to a good set of defaults */
    694	for (i = 0; i < ARRAY_SIZE(cx24123_regdata); i++)
    695		cx24123_writereg(state, cx24123_regdata[i].reg,
    696			cx24123_regdata[i].data);
    697
    698	/* Set the LNB polarity */
    699	if (state->config->lnb_polarity)
    700		cx24123_writereg(state, 0x32,
    701			cx24123_readreg(state, 0x32) | 0x02);
    702
    703	if (state->config->dont_use_pll)
    704		cx24123_repeater_mode(state, 1, 0);
    705
    706	return 0;
    707}
    708
    709static int cx24123_set_voltage(struct dvb_frontend *fe,
    710			       enum fe_sec_voltage voltage)
    711{
    712	struct cx24123_state *state = fe->demodulator_priv;
    713	u8 val;
    714
    715	val = cx24123_readreg(state, 0x29) & ~0x40;
    716
    717	switch (voltage) {
    718	case SEC_VOLTAGE_13:
    719		dprintk("setting voltage 13V\n");
    720		return cx24123_writereg(state, 0x29, val & 0x7f);
    721	case SEC_VOLTAGE_18:
    722		dprintk("setting voltage 18V\n");
    723		return cx24123_writereg(state, 0x29, val | 0x80);
    724	case SEC_VOLTAGE_OFF:
    725		/* already handled in cx88-dvb */
    726		return 0;
    727	default:
    728		return -EINVAL;
    729	}
    730
    731	return 0;
    732}
    733
    734/* wait for diseqc queue to become ready (or timeout) */
    735static void cx24123_wait_for_diseqc(struct cx24123_state *state)
    736{
    737	unsigned long timeout = jiffies + msecs_to_jiffies(200);
    738	while (!(cx24123_readreg(state, 0x29) & 0x40)) {
    739		if (time_after(jiffies, timeout)) {
    740			err("%s: diseqc queue not ready, " \
    741				"command may be lost.\n", __func__);
    742			break;
    743		}
    744		msleep(10);
    745	}
    746}
    747
    748static int cx24123_send_diseqc_msg(struct dvb_frontend *fe,
    749	struct dvb_diseqc_master_cmd *cmd)
    750{
    751	struct cx24123_state *state = fe->demodulator_priv;
    752	int i, val, tone;
    753
    754	dprintk("\n");
    755
    756	/* stop continuous tone if enabled */
    757	tone = cx24123_readreg(state, 0x29);
    758	if (tone & 0x10)
    759		cx24123_writereg(state, 0x29, tone & ~0x50);
    760
    761	/* wait for diseqc queue ready */
    762	cx24123_wait_for_diseqc(state);
    763
    764	/* select tone mode */
    765	cx24123_writereg(state, 0x2a, cx24123_readreg(state, 0x2a) & 0xfb);
    766
    767	for (i = 0; i < cmd->msg_len; i++)
    768		cx24123_writereg(state, 0x2C + i, cmd->msg[i]);
    769
    770	val = cx24123_readreg(state, 0x29);
    771	cx24123_writereg(state, 0x29, ((val & 0x90) | 0x40) |
    772		((cmd->msg_len-3) & 3));
    773
    774	/* wait for diseqc message to finish sending */
    775	cx24123_wait_for_diseqc(state);
    776
    777	/* restart continuous tone if enabled */
    778	if (tone & 0x10)
    779		cx24123_writereg(state, 0x29, tone & ~0x40);
    780
    781	return 0;
    782}
    783
    784static int cx24123_diseqc_send_burst(struct dvb_frontend *fe,
    785				     enum fe_sec_mini_cmd burst)
    786{
    787	struct cx24123_state *state = fe->demodulator_priv;
    788	int val, tone;
    789
    790	dprintk("\n");
    791
    792	/* stop continuous tone if enabled */
    793	tone = cx24123_readreg(state, 0x29);
    794	if (tone & 0x10)
    795		cx24123_writereg(state, 0x29, tone & ~0x50);
    796
    797	/* wait for diseqc queue ready */
    798	cx24123_wait_for_diseqc(state);
    799
    800	/* select tone mode */
    801	cx24123_writereg(state, 0x2a, cx24123_readreg(state, 0x2a) | 0x4);
    802	msleep(30);
    803	val = cx24123_readreg(state, 0x29);
    804	if (burst == SEC_MINI_A)
    805		cx24123_writereg(state, 0x29, ((val & 0x90) | 0x40 | 0x00));
    806	else if (burst == SEC_MINI_B)
    807		cx24123_writereg(state, 0x29, ((val & 0x90) | 0x40 | 0x08));
    808	else
    809		return -EINVAL;
    810
    811	cx24123_wait_for_diseqc(state);
    812	cx24123_writereg(state, 0x2a, cx24123_readreg(state, 0x2a) & 0xfb);
    813
    814	/* restart continuous tone if enabled */
    815	if (tone & 0x10)
    816		cx24123_writereg(state, 0x29, tone & ~0x40);
    817
    818	return 0;
    819}
    820
    821static int cx24123_read_status(struct dvb_frontend *fe, enum fe_status *status)
    822{
    823	struct cx24123_state *state = fe->demodulator_priv;
    824	int sync = cx24123_readreg(state, 0x14);
    825
    826	*status = 0;
    827	if (state->config->dont_use_pll) {
    828		u32 tun_status = 0;
    829		if (fe->ops.tuner_ops.get_status)
    830			fe->ops.tuner_ops.get_status(fe, &tun_status);
    831		if (tun_status & TUNER_STATUS_LOCKED)
    832			*status |= FE_HAS_SIGNAL;
    833	} else {
    834		int lock = cx24123_readreg(state, 0x20);
    835		if (lock & 0x01)
    836			*status |= FE_HAS_SIGNAL;
    837	}
    838
    839	if (sync & 0x02)
    840		*status |= FE_HAS_CARRIER;	/* Phase locked */
    841	if (sync & 0x04)
    842		*status |= FE_HAS_VITERBI;
    843
    844	/* Reed-Solomon Status */
    845	if (sync & 0x08)
    846		*status |= FE_HAS_SYNC;
    847	if (sync & 0x80)
    848		*status |= FE_HAS_LOCK;		/*Full Sync */
    849
    850	return 0;
    851}
    852
    853/*
    854 * Configured to return the measurement of errors in blocks,
    855 * because no UCBLOCKS value is available, so this value doubles up
    856 * to satisfy both measurements.
    857 */
    858static int cx24123_read_ber(struct dvb_frontend *fe, u32 *ber)
    859{
    860	struct cx24123_state *state = fe->demodulator_priv;
    861
    862	/* The true bit error rate is this value divided by
    863	   the window size (set as 256 * 255) */
    864	*ber = ((cx24123_readreg(state, 0x1c) & 0x3f) << 16) |
    865		(cx24123_readreg(state, 0x1d) << 8 |
    866		 cx24123_readreg(state, 0x1e));
    867
    868	dprintk("BER = %d\n", *ber);
    869
    870	return 0;
    871}
    872
    873static int cx24123_read_signal_strength(struct dvb_frontend *fe,
    874	u16 *signal_strength)
    875{
    876	struct cx24123_state *state = fe->demodulator_priv;
    877
    878	/* larger = better */
    879	*signal_strength = cx24123_readreg(state, 0x3b) << 8;
    880
    881	dprintk("Signal strength = %d\n", *signal_strength);
    882
    883	return 0;
    884}
    885
    886static int cx24123_read_snr(struct dvb_frontend *fe, u16 *snr)
    887{
    888	struct cx24123_state *state = fe->demodulator_priv;
    889
    890	/* Inverted raw Es/N0 count, totally bogus but better than the
    891	   BER threshold. */
    892	*snr = 65535 - (((u16)cx24123_readreg(state, 0x18) << 8) |
    893			 (u16)cx24123_readreg(state, 0x19));
    894
    895	dprintk("read S/N index = %d\n", *snr);
    896
    897	return 0;
    898}
    899
    900static int cx24123_set_frontend(struct dvb_frontend *fe)
    901{
    902	struct cx24123_state *state = fe->demodulator_priv;
    903	struct dtv_frontend_properties *p = &fe->dtv_property_cache;
    904
    905	dprintk("\n");
    906
    907	if (state->config->set_ts_params)
    908		state->config->set_ts_params(fe, 0);
    909
    910	state->currentfreq = p->frequency;
    911	state->currentsymbolrate = p->symbol_rate;
    912
    913	cx24123_set_inversion(state, p->inversion);
    914	cx24123_set_fec(state, p->fec_inner);
    915	cx24123_set_symbolrate(state, p->symbol_rate);
    916
    917	if (!state->config->dont_use_pll)
    918		cx24123_pll_tune(fe);
    919	else if (fe->ops.tuner_ops.set_params)
    920		fe->ops.tuner_ops.set_params(fe);
    921	else
    922		err("it seems I don't have a tuner...");
    923
    924	/* Enable automatic acquisition and reset cycle */
    925	cx24123_writereg(state, 0x03, (cx24123_readreg(state, 0x03) | 0x07));
    926	cx24123_writereg(state, 0x00, 0x10);
    927	cx24123_writereg(state, 0x00, 0);
    928
    929	if (state->config->agc_callback)
    930		state->config->agc_callback(fe);
    931
    932	return 0;
    933}
    934
    935static int cx24123_get_frontend(struct dvb_frontend *fe,
    936				struct dtv_frontend_properties *p)
    937{
    938	struct cx24123_state *state = fe->demodulator_priv;
    939
    940	dprintk("\n");
    941
    942	if (cx24123_get_inversion(state, &p->inversion) != 0) {
    943		err("%s: Failed to get inversion status\n", __func__);
    944		return -EREMOTEIO;
    945	}
    946	if (cx24123_get_fec(state, &p->fec_inner) != 0) {
    947		err("%s: Failed to get fec status\n", __func__);
    948		return -EREMOTEIO;
    949	}
    950	p->frequency = state->currentfreq;
    951	p->symbol_rate = state->currentsymbolrate;
    952
    953	return 0;
    954}
    955
    956static int cx24123_set_tone(struct dvb_frontend *fe, enum fe_sec_tone_mode tone)
    957{
    958	struct cx24123_state *state = fe->demodulator_priv;
    959	u8 val;
    960
    961	/* wait for diseqc queue ready */
    962	cx24123_wait_for_diseqc(state);
    963
    964	val = cx24123_readreg(state, 0x29) & ~0x40;
    965
    966	switch (tone) {
    967	case SEC_TONE_ON:
    968		dprintk("setting tone on\n");
    969		return cx24123_writereg(state, 0x29, val | 0x10);
    970	case SEC_TONE_OFF:
    971		dprintk("setting tone off\n");
    972		return cx24123_writereg(state, 0x29, val & 0xef);
    973	default:
    974		err("CASE reached default with tone=%d\n", tone);
    975		return -EINVAL;
    976	}
    977
    978	return 0;
    979}
    980
    981static int cx24123_tune(struct dvb_frontend *fe,
    982			bool re_tune,
    983			unsigned int mode_flags,
    984			unsigned int *delay,
    985			enum fe_status *status)
    986{
    987	int retval = 0;
    988
    989	if (re_tune)
    990		retval = cx24123_set_frontend(fe);
    991
    992	if (!(mode_flags & FE_TUNE_MODE_ONESHOT))
    993		cx24123_read_status(fe, status);
    994	*delay = HZ/10;
    995
    996	return retval;
    997}
    998
    999static enum dvbfe_algo cx24123_get_algo(struct dvb_frontend *fe)
   1000{
   1001	return DVBFE_ALGO_HW;
   1002}
   1003
   1004static void cx24123_release(struct dvb_frontend *fe)
   1005{
   1006	struct cx24123_state *state = fe->demodulator_priv;
   1007	dprintk("\n");
   1008	i2c_del_adapter(&state->tuner_i2c_adapter);
   1009	kfree(state);
   1010}
   1011
   1012static int cx24123_tuner_i2c_tuner_xfer(struct i2c_adapter *i2c_adap,
   1013	struct i2c_msg msg[], int num)
   1014{
   1015	struct cx24123_state *state = i2c_get_adapdata(i2c_adap);
   1016	/* this repeater closes after the first stop */
   1017	cx24123_repeater_mode(state, 1, 1);
   1018	return i2c_transfer(state->i2c, msg, num);
   1019}
   1020
   1021static u32 cx24123_tuner_i2c_func(struct i2c_adapter *adapter)
   1022{
   1023	return I2C_FUNC_I2C;
   1024}
   1025
   1026static const struct i2c_algorithm cx24123_tuner_i2c_algo = {
   1027	.master_xfer   = cx24123_tuner_i2c_tuner_xfer,
   1028	.functionality = cx24123_tuner_i2c_func,
   1029};
   1030
   1031struct i2c_adapter *
   1032	cx24123_get_tuner_i2c_adapter(struct dvb_frontend *fe)
   1033{
   1034	struct cx24123_state *state = fe->demodulator_priv;
   1035	return &state->tuner_i2c_adapter;
   1036}
   1037EXPORT_SYMBOL(cx24123_get_tuner_i2c_adapter);
   1038
   1039static const struct dvb_frontend_ops cx24123_ops;
   1040
   1041struct dvb_frontend *cx24123_attach(const struct cx24123_config *config,
   1042				    struct i2c_adapter *i2c)
   1043{
   1044	/* allocate memory for the internal state */
   1045	struct cx24123_state *state =
   1046		kzalloc(sizeof(struct cx24123_state), GFP_KERNEL);
   1047
   1048	dprintk("\n");
   1049	if (state == NULL) {
   1050		err("Unable to kzalloc\n");
   1051		goto error;
   1052	}
   1053
   1054	/* setup the state */
   1055	state->config = config;
   1056	state->i2c = i2c;
   1057
   1058	/* check if the demod is there */
   1059	state->demod_rev = cx24123_readreg(state, 0x00);
   1060	switch (state->demod_rev) {
   1061	case 0xe1:
   1062		info("detected CX24123C\n");
   1063		break;
   1064	case 0xd1:
   1065		info("detected CX24123\n");
   1066		break;
   1067	default:
   1068		err("wrong demod revision: %x\n", state->demod_rev);
   1069		goto error;
   1070	}
   1071
   1072	/* create dvb_frontend */
   1073	memcpy(&state->frontend.ops, &cx24123_ops,
   1074		sizeof(struct dvb_frontend_ops));
   1075	state->frontend.demodulator_priv = state;
   1076
   1077	/* create tuner i2c adapter */
   1078	if (config->dont_use_pll)
   1079		cx24123_repeater_mode(state, 1, 0);
   1080
   1081	strscpy(state->tuner_i2c_adapter.name, "CX24123 tuner I2C bus",
   1082		sizeof(state->tuner_i2c_adapter.name));
   1083	state->tuner_i2c_adapter.algo      = &cx24123_tuner_i2c_algo;
   1084	state->tuner_i2c_adapter.algo_data = NULL;
   1085	state->tuner_i2c_adapter.dev.parent = i2c->dev.parent;
   1086	i2c_set_adapdata(&state->tuner_i2c_adapter, state);
   1087	if (i2c_add_adapter(&state->tuner_i2c_adapter) < 0) {
   1088		err("tuner i2c bus could not be initialized\n");
   1089		goto error;
   1090	}
   1091
   1092	return &state->frontend;
   1093
   1094error:
   1095	kfree(state);
   1096
   1097	return NULL;
   1098}
   1099EXPORT_SYMBOL(cx24123_attach);
   1100
   1101static const struct dvb_frontend_ops cx24123_ops = {
   1102	.delsys = { SYS_DVBS },
   1103	.info = {
   1104		.name = "Conexant CX24123/CX24109",
   1105		.frequency_min_hz =  950 * MHz,
   1106		.frequency_max_hz = 2150 * MHz,
   1107		.frequency_stepsize_hz = 1011 * kHz,
   1108		.frequency_tolerance_hz = 5 * MHz,
   1109		.symbol_rate_min = 1000000,
   1110		.symbol_rate_max = 45000000,
   1111		.caps = FE_CAN_INVERSION_AUTO |
   1112			FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4 |
   1113			FE_CAN_FEC_4_5 | FE_CAN_FEC_5_6 | FE_CAN_FEC_6_7 |
   1114			FE_CAN_FEC_7_8 | FE_CAN_FEC_AUTO |
   1115			FE_CAN_QPSK | FE_CAN_RECOVER
   1116	},
   1117
   1118	.release = cx24123_release,
   1119
   1120	.init = cx24123_initfe,
   1121	.set_frontend = cx24123_set_frontend,
   1122	.get_frontend = cx24123_get_frontend,
   1123	.read_status = cx24123_read_status,
   1124	.read_ber = cx24123_read_ber,
   1125	.read_signal_strength = cx24123_read_signal_strength,
   1126	.read_snr = cx24123_read_snr,
   1127	.diseqc_send_master_cmd = cx24123_send_diseqc_msg,
   1128	.diseqc_send_burst = cx24123_diseqc_send_burst,
   1129	.set_tone = cx24123_set_tone,
   1130	.set_voltage = cx24123_set_voltage,
   1131	.tune = cx24123_tune,
   1132	.get_frontend_algo = cx24123_get_algo,
   1133};
   1134
   1135MODULE_DESCRIPTION("DVB Frontend module for Conexant " \
   1136	"CX24123/CX24109/CX24113 hardware");
   1137MODULE_AUTHOR("Steven Toth");
   1138MODULE_LICENSE("GPL");
   1139