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

lgdt3305.c (31246B)


      1// SPDX-License-Identifier: GPL-2.0-or-later
      2/*
      3 *    Support for LG Electronics LGDT3304 and LGDT3305 - VSB/QAM
      4 *
      5 *    Copyright (C) 2008, 2009, 2010 Michael Krufky <mkrufky@linuxtv.org>
      6 *
      7 *    LGDT3304 support by Jarod Wilson <jarod@redhat.com>
      8 */
      9
     10#include <asm/div64.h>
     11#include <linux/dvb/frontend.h>
     12#include <linux/slab.h>
     13#include <media/dvb_math.h>
     14#include "lgdt3305.h"
     15
     16static int debug;
     17module_param(debug, int, 0644);
     18MODULE_PARM_DESC(debug, "set debug level (info=1, reg=2 (or-able))");
     19
     20#define DBG_INFO 1
     21#define DBG_REG  2
     22
     23#define lg_printk(kern, fmt, arg...)					\
     24	printk(kern "%s: " fmt, __func__, ##arg)
     25
     26#define lg_info(fmt, arg...)	printk(KERN_INFO "lgdt3305: " fmt, ##arg)
     27#define lg_warn(fmt, arg...)	lg_printk(KERN_WARNING,       fmt, ##arg)
     28#define lg_err(fmt, arg...)	lg_printk(KERN_ERR,           fmt, ##arg)
     29#define lg_dbg(fmt, arg...) if (debug & DBG_INFO)			\
     30				lg_printk(KERN_DEBUG,         fmt, ##arg)
     31#define lg_reg(fmt, arg...) if (debug & DBG_REG)			\
     32				lg_printk(KERN_DEBUG,         fmt, ##arg)
     33
     34#define lg_fail(ret)							\
     35({									\
     36	int __ret;							\
     37	__ret = (ret < 0);						\
     38	if (__ret)							\
     39		lg_err("error %d on line %d\n",	ret, __LINE__);		\
     40	__ret;								\
     41})
     42
     43struct lgdt3305_state {
     44	struct i2c_adapter *i2c_adap;
     45	const struct lgdt3305_config *cfg;
     46
     47	struct dvb_frontend frontend;
     48
     49	enum fe_modulation current_modulation;
     50	u32 current_frequency;
     51	u32 snr;
     52};
     53
     54/* ------------------------------------------------------------------------ */
     55
     56/* FIXME: verify & document the LGDT3304 registers */
     57
     58#define LGDT3305_GEN_CTRL_1                   0x0000
     59#define LGDT3305_GEN_CTRL_2                   0x0001
     60#define LGDT3305_GEN_CTRL_3                   0x0002
     61#define LGDT3305_GEN_STATUS                   0x0003
     62#define LGDT3305_GEN_CONTROL                  0x0007
     63#define LGDT3305_GEN_CTRL_4                   0x000a
     64#define LGDT3305_DGTL_AGC_REF_1               0x0012
     65#define LGDT3305_DGTL_AGC_REF_2               0x0013
     66#define LGDT3305_CR_CTR_FREQ_1                0x0106
     67#define LGDT3305_CR_CTR_FREQ_2                0x0107
     68#define LGDT3305_CR_CTR_FREQ_3                0x0108
     69#define LGDT3305_CR_CTR_FREQ_4                0x0109
     70#define LGDT3305_CR_MSE_1                     0x011b
     71#define LGDT3305_CR_MSE_2                     0x011c
     72#define LGDT3305_CR_LOCK_STATUS               0x011d
     73#define LGDT3305_CR_CTRL_7                    0x0126
     74#define LGDT3305_AGC_POWER_REF_1              0x0300
     75#define LGDT3305_AGC_POWER_REF_2              0x0301
     76#define LGDT3305_AGC_DELAY_PT_1               0x0302
     77#define LGDT3305_AGC_DELAY_PT_2               0x0303
     78#define LGDT3305_RFAGC_LOOP_FLTR_BW_1         0x0306
     79#define LGDT3305_RFAGC_LOOP_FLTR_BW_2         0x0307
     80#define LGDT3305_IFBW_1                       0x0308
     81#define LGDT3305_IFBW_2                       0x0309
     82#define LGDT3305_AGC_CTRL_1                   0x030c
     83#define LGDT3305_AGC_CTRL_4                   0x0314
     84#define LGDT3305_EQ_MSE_1                     0x0413
     85#define LGDT3305_EQ_MSE_2                     0x0414
     86#define LGDT3305_EQ_MSE_3                     0x0415
     87#define LGDT3305_PT_MSE_1                     0x0417
     88#define LGDT3305_PT_MSE_2                     0x0418
     89#define LGDT3305_PT_MSE_3                     0x0419
     90#define LGDT3305_FEC_BLOCK_CTRL               0x0504
     91#define LGDT3305_FEC_LOCK_STATUS              0x050a
     92#define LGDT3305_FEC_PKT_ERR_1                0x050c
     93#define LGDT3305_FEC_PKT_ERR_2                0x050d
     94#define LGDT3305_TP_CTRL_1                    0x050e
     95#define LGDT3305_BERT_PERIOD                  0x0801
     96#define LGDT3305_BERT_ERROR_COUNT_1           0x080a
     97#define LGDT3305_BERT_ERROR_COUNT_2           0x080b
     98#define LGDT3305_BERT_ERROR_COUNT_3           0x080c
     99#define LGDT3305_BERT_ERROR_COUNT_4           0x080d
    100
    101static int lgdt3305_write_reg(struct lgdt3305_state *state, u16 reg, u8 val)
    102{
    103	int ret;
    104	u8 buf[] = { reg >> 8, reg & 0xff, val };
    105	struct i2c_msg msg = {
    106		.addr = state->cfg->i2c_addr, .flags = 0,
    107		.buf = buf, .len = 3,
    108	};
    109
    110	lg_reg("reg: 0x%04x, val: 0x%02x\n", reg, val);
    111
    112	ret = i2c_transfer(state->i2c_adap, &msg, 1);
    113
    114	if (ret != 1) {
    115		lg_err("error (addr %02x %02x <- %02x, err = %i)\n",
    116		       msg.buf[0], msg.buf[1], msg.buf[2], ret);
    117		if (ret < 0)
    118			return ret;
    119		else
    120			return -EREMOTEIO;
    121	}
    122	return 0;
    123}
    124
    125static int lgdt3305_read_reg(struct lgdt3305_state *state, u16 reg, u8 *val)
    126{
    127	int ret;
    128	u8 reg_buf[] = { reg >> 8, reg & 0xff };
    129	struct i2c_msg msg[] = {
    130		{ .addr = state->cfg->i2c_addr,
    131		  .flags = 0, .buf = reg_buf, .len = 2 },
    132		{ .addr = state->cfg->i2c_addr,
    133		  .flags = I2C_M_RD, .buf = val, .len = 1 },
    134	};
    135
    136	lg_reg("reg: 0x%04x\n", reg);
    137
    138	ret = i2c_transfer(state->i2c_adap, msg, 2);
    139
    140	if (ret != 2) {
    141		lg_err("error (addr %02x reg %04x error (ret == %i)\n",
    142		       state->cfg->i2c_addr, reg, ret);
    143		if (ret < 0)
    144			return ret;
    145		else
    146			return -EREMOTEIO;
    147	}
    148	return 0;
    149}
    150
    151#define read_reg(state, reg)						\
    152({									\
    153	u8 __val;							\
    154	int ret = lgdt3305_read_reg(state, reg, &__val);		\
    155	if (lg_fail(ret))						\
    156		__val = 0;						\
    157	__val;								\
    158})
    159
    160static int lgdt3305_set_reg_bit(struct lgdt3305_state *state,
    161				u16 reg, int bit, int onoff)
    162{
    163	u8 val;
    164	int ret;
    165
    166	lg_reg("reg: 0x%04x, bit: %d, level: %d\n", reg, bit, onoff);
    167
    168	ret = lgdt3305_read_reg(state, reg, &val);
    169	if (lg_fail(ret))
    170		goto fail;
    171
    172	val &= ~(1 << bit);
    173	val |= (onoff & 1) << bit;
    174
    175	ret = lgdt3305_write_reg(state, reg, val);
    176fail:
    177	return ret;
    178}
    179
    180struct lgdt3305_reg {
    181	u16 reg;
    182	u8 val;
    183};
    184
    185static int lgdt3305_write_regs(struct lgdt3305_state *state,
    186			       struct lgdt3305_reg *regs, int len)
    187{
    188	int i, ret;
    189
    190	lg_reg("writing %d registers...\n", len);
    191
    192	for (i = 0; i < len - 1; i++) {
    193		ret = lgdt3305_write_reg(state, regs[i].reg, regs[i].val);
    194		if (lg_fail(ret))
    195			return ret;
    196	}
    197	return 0;
    198}
    199
    200/* ------------------------------------------------------------------------ */
    201
    202static int lgdt3305_soft_reset(struct lgdt3305_state *state)
    203{
    204	int ret;
    205
    206	lg_dbg("\n");
    207
    208	ret = lgdt3305_set_reg_bit(state, LGDT3305_GEN_CTRL_3, 0, 0);
    209	if (lg_fail(ret))
    210		goto fail;
    211
    212	msleep(20);
    213	ret = lgdt3305_set_reg_bit(state, LGDT3305_GEN_CTRL_3, 0, 1);
    214fail:
    215	return ret;
    216}
    217
    218static inline int lgdt3305_mpeg_mode(struct lgdt3305_state *state,
    219				     enum lgdt3305_mpeg_mode mode)
    220{
    221	lg_dbg("(%d)\n", mode);
    222	return lgdt3305_set_reg_bit(state, LGDT3305_TP_CTRL_1, 5, mode);
    223}
    224
    225static int lgdt3305_mpeg_mode_polarity(struct lgdt3305_state *state)
    226{
    227	u8 val;
    228	int ret;
    229	enum lgdt3305_tp_clock_edge edge = state->cfg->tpclk_edge;
    230	enum lgdt3305_tp_clock_mode mode = state->cfg->tpclk_mode;
    231	enum lgdt3305_tp_valid_polarity valid = state->cfg->tpvalid_polarity;
    232
    233	lg_dbg("edge = %d, valid = %d\n", edge, valid);
    234
    235	ret = lgdt3305_read_reg(state, LGDT3305_TP_CTRL_1, &val);
    236	if (lg_fail(ret))
    237		goto fail;
    238
    239	val &= ~0x09;
    240
    241	if (edge)
    242		val |= 0x08;
    243	if (mode)
    244		val |= 0x40;
    245	if (valid)
    246		val |= 0x01;
    247
    248	ret = lgdt3305_write_reg(state, LGDT3305_TP_CTRL_1, val);
    249	if (lg_fail(ret))
    250		goto fail;
    251
    252	ret = lgdt3305_soft_reset(state);
    253fail:
    254	return ret;
    255}
    256
    257static int lgdt3305_set_modulation(struct lgdt3305_state *state,
    258				   struct dtv_frontend_properties *p)
    259{
    260	u8 opermode;
    261	int ret;
    262
    263	lg_dbg("\n");
    264
    265	ret = lgdt3305_read_reg(state, LGDT3305_GEN_CTRL_1, &opermode);
    266	if (lg_fail(ret))
    267		goto fail;
    268
    269	opermode &= ~0x03;
    270
    271	switch (p->modulation) {
    272	case VSB_8:
    273		opermode |= 0x03;
    274		break;
    275	case QAM_64:
    276		opermode |= 0x00;
    277		break;
    278	case QAM_256:
    279		opermode |= 0x01;
    280		break;
    281	default:
    282		return -EINVAL;
    283	}
    284	ret = lgdt3305_write_reg(state, LGDT3305_GEN_CTRL_1, opermode);
    285fail:
    286	return ret;
    287}
    288
    289static int lgdt3305_set_filter_extension(struct lgdt3305_state *state,
    290					 struct dtv_frontend_properties *p)
    291{
    292	int val;
    293
    294	switch (p->modulation) {
    295	case VSB_8:
    296		val = 0;
    297		break;
    298	case QAM_64:
    299	case QAM_256:
    300		val = 1;
    301		break;
    302	default:
    303		return -EINVAL;
    304	}
    305	lg_dbg("val = %d\n", val);
    306
    307	return lgdt3305_set_reg_bit(state, 0x043f, 2, val);
    308}
    309
    310/* ------------------------------------------------------------------------ */
    311
    312static int lgdt3305_passband_digital_agc(struct lgdt3305_state *state,
    313					 struct dtv_frontend_properties *p)
    314{
    315	u16 agc_ref;
    316
    317	switch (p->modulation) {
    318	case VSB_8:
    319		agc_ref = 0x32c4;
    320		break;
    321	case QAM_64:
    322		agc_ref = 0x2a00;
    323		break;
    324	case QAM_256:
    325		agc_ref = 0x2a80;
    326		break;
    327	default:
    328		return -EINVAL;
    329	}
    330
    331	lg_dbg("agc ref: 0x%04x\n", agc_ref);
    332
    333	lgdt3305_write_reg(state, LGDT3305_DGTL_AGC_REF_1, agc_ref >> 8);
    334	lgdt3305_write_reg(state, LGDT3305_DGTL_AGC_REF_2, agc_ref & 0xff);
    335
    336	return 0;
    337}
    338
    339static int lgdt3305_rfagc_loop(struct lgdt3305_state *state,
    340			       struct dtv_frontend_properties *p)
    341{
    342	u16 ifbw, rfbw, agcdelay;
    343
    344	switch (p->modulation) {
    345	case VSB_8:
    346		agcdelay = 0x04c0;
    347		rfbw     = 0x8000;
    348		ifbw     = 0x8000;
    349		break;
    350	case QAM_64:
    351	case QAM_256:
    352		agcdelay = 0x046b;
    353		rfbw     = 0x8889;
    354		/* FIXME: investigate optimal ifbw & rfbw values for the
    355		 *        DT3304 and re-write this switch..case block */
    356		if (state->cfg->demod_chip == LGDT3304)
    357			ifbw = 0x6666;
    358		else /* (state->cfg->demod_chip == LGDT3305) */
    359			ifbw = 0x8888;
    360		break;
    361	default:
    362		return -EINVAL;
    363	}
    364
    365	if (state->cfg->rf_agc_loop) {
    366		lg_dbg("agcdelay: 0x%04x, rfbw: 0x%04x\n", agcdelay, rfbw);
    367
    368		/* rf agc loop filter bandwidth */
    369		lgdt3305_write_reg(state, LGDT3305_AGC_DELAY_PT_1,
    370				   agcdelay >> 8);
    371		lgdt3305_write_reg(state, LGDT3305_AGC_DELAY_PT_2,
    372				   agcdelay & 0xff);
    373
    374		lgdt3305_write_reg(state, LGDT3305_RFAGC_LOOP_FLTR_BW_1,
    375				   rfbw >> 8);
    376		lgdt3305_write_reg(state, LGDT3305_RFAGC_LOOP_FLTR_BW_2,
    377				   rfbw & 0xff);
    378	} else {
    379		lg_dbg("ifbw: 0x%04x\n", ifbw);
    380
    381		/* if agc loop filter bandwidth */
    382		lgdt3305_write_reg(state, LGDT3305_IFBW_1, ifbw >> 8);
    383		lgdt3305_write_reg(state, LGDT3305_IFBW_2, ifbw & 0xff);
    384	}
    385
    386	return 0;
    387}
    388
    389static int lgdt3305_agc_setup(struct lgdt3305_state *state,
    390			      struct dtv_frontend_properties *p)
    391{
    392	int lockdten, acqen;
    393
    394	switch (p->modulation) {
    395	case VSB_8:
    396		lockdten = 0;
    397		acqen = 0;
    398		break;
    399	case QAM_64:
    400	case QAM_256:
    401		lockdten = 1;
    402		acqen = 1;
    403		break;
    404	default:
    405		return -EINVAL;
    406	}
    407
    408	lg_dbg("lockdten = %d, acqen = %d\n", lockdten, acqen);
    409
    410	/* control agc function */
    411	switch (state->cfg->demod_chip) {
    412	case LGDT3304:
    413		lgdt3305_write_reg(state, 0x0314, 0xe1 | lockdten << 1);
    414		lgdt3305_set_reg_bit(state, 0x030e, 2, acqen);
    415		break;
    416	case LGDT3305:
    417		lgdt3305_write_reg(state, LGDT3305_AGC_CTRL_4, 0xe1 | lockdten << 1);
    418		lgdt3305_set_reg_bit(state, LGDT3305_AGC_CTRL_1, 2, acqen);
    419		break;
    420	default:
    421		return -EINVAL;
    422	}
    423
    424	return lgdt3305_rfagc_loop(state, p);
    425}
    426
    427static int lgdt3305_set_agc_power_ref(struct lgdt3305_state *state,
    428				      struct dtv_frontend_properties *p)
    429{
    430	u16 usref = 0;
    431
    432	switch (p->modulation) {
    433	case VSB_8:
    434		if (state->cfg->usref_8vsb)
    435			usref = state->cfg->usref_8vsb;
    436		break;
    437	case QAM_64:
    438		if (state->cfg->usref_qam64)
    439			usref = state->cfg->usref_qam64;
    440		break;
    441	case QAM_256:
    442		if (state->cfg->usref_qam256)
    443			usref = state->cfg->usref_qam256;
    444		break;
    445	default:
    446		return -EINVAL;
    447	}
    448
    449	if (usref) {
    450		lg_dbg("set manual mode: 0x%04x\n", usref);
    451
    452		lgdt3305_set_reg_bit(state, LGDT3305_AGC_CTRL_1, 3, 1);
    453
    454		lgdt3305_write_reg(state, LGDT3305_AGC_POWER_REF_1,
    455				   0xff & (usref >> 8));
    456		lgdt3305_write_reg(state, LGDT3305_AGC_POWER_REF_2,
    457				   0xff & (usref >> 0));
    458	}
    459	return 0;
    460}
    461
    462/* ------------------------------------------------------------------------ */
    463
    464static int lgdt3305_spectral_inversion(struct lgdt3305_state *state,
    465				       struct dtv_frontend_properties *p,
    466				       int inversion)
    467{
    468	int ret;
    469
    470	lg_dbg("(%d)\n", inversion);
    471
    472	switch (p->modulation) {
    473	case VSB_8:
    474		ret = lgdt3305_write_reg(state, LGDT3305_CR_CTRL_7,
    475					 inversion ? 0xf9 : 0x79);
    476		break;
    477	case QAM_64:
    478	case QAM_256:
    479		ret = lgdt3305_write_reg(state, LGDT3305_FEC_BLOCK_CTRL,
    480					 inversion ? 0xfd : 0xff);
    481		break;
    482	default:
    483		ret = -EINVAL;
    484	}
    485	return ret;
    486}
    487
    488static int lgdt3305_set_if(struct lgdt3305_state *state,
    489			   struct dtv_frontend_properties *p)
    490{
    491	u16 if_freq_khz;
    492	u8 nco1, nco2, nco3, nco4;
    493	u64 nco;
    494
    495	switch (p->modulation) {
    496	case VSB_8:
    497		if_freq_khz = state->cfg->vsb_if_khz;
    498		break;
    499	case QAM_64:
    500	case QAM_256:
    501		if_freq_khz = state->cfg->qam_if_khz;
    502		break;
    503	default:
    504		return -EINVAL;
    505	}
    506
    507	nco = if_freq_khz / 10;
    508
    509	switch (p->modulation) {
    510	case VSB_8:
    511		nco <<= 24;
    512		do_div(nco, 625);
    513		break;
    514	case QAM_64:
    515	case QAM_256:
    516		nco <<= 28;
    517		do_div(nco, 625);
    518		break;
    519	default:
    520		return -EINVAL;
    521	}
    522
    523	nco1 = (nco >> 24) & 0x3f;
    524	nco1 |= 0x40;
    525	nco2 = (nco >> 16) & 0xff;
    526	nco3 = (nco >> 8) & 0xff;
    527	nco4 = nco & 0xff;
    528
    529	lgdt3305_write_reg(state, LGDT3305_CR_CTR_FREQ_1, nco1);
    530	lgdt3305_write_reg(state, LGDT3305_CR_CTR_FREQ_2, nco2);
    531	lgdt3305_write_reg(state, LGDT3305_CR_CTR_FREQ_3, nco3);
    532	lgdt3305_write_reg(state, LGDT3305_CR_CTR_FREQ_4, nco4);
    533
    534	lg_dbg("%d KHz -> [%02x%02x%02x%02x]\n",
    535	       if_freq_khz, nco1, nco2, nco3, nco4);
    536
    537	return 0;
    538}
    539
    540/* ------------------------------------------------------------------------ */
    541
    542static int lgdt3305_i2c_gate_ctrl(struct dvb_frontend *fe, int enable)
    543{
    544	struct lgdt3305_state *state = fe->demodulator_priv;
    545
    546	if (state->cfg->deny_i2c_rptr)
    547		return 0;
    548
    549	lg_dbg("(%d)\n", enable);
    550
    551	return lgdt3305_set_reg_bit(state, LGDT3305_GEN_CTRL_2, 5,
    552				    enable ? 0 : 1);
    553}
    554
    555static int lgdt3305_sleep(struct dvb_frontend *fe)
    556{
    557	struct lgdt3305_state *state = fe->demodulator_priv;
    558	u8 gen_ctrl_3, gen_ctrl_4;
    559
    560	lg_dbg("\n");
    561
    562	gen_ctrl_3 = read_reg(state, LGDT3305_GEN_CTRL_3);
    563	gen_ctrl_4 = read_reg(state, LGDT3305_GEN_CTRL_4);
    564
    565	/* hold in software reset while sleeping */
    566	gen_ctrl_3 &= ~0x01;
    567	/* tristate the IF-AGC pin */
    568	gen_ctrl_3 |=  0x02;
    569	/* tristate the RF-AGC pin */
    570	gen_ctrl_3 |=  0x04;
    571
    572	/* disable vsb/qam module */
    573	gen_ctrl_4 &= ~0x01;
    574	/* disable adc module */
    575	gen_ctrl_4 &= ~0x02;
    576
    577	lgdt3305_write_reg(state, LGDT3305_GEN_CTRL_3, gen_ctrl_3);
    578	lgdt3305_write_reg(state, LGDT3305_GEN_CTRL_4, gen_ctrl_4);
    579
    580	return 0;
    581}
    582
    583static int lgdt3305_init(struct dvb_frontend *fe)
    584{
    585	struct lgdt3305_state *state = fe->demodulator_priv;
    586	int ret;
    587
    588	static struct lgdt3305_reg lgdt3304_init_data[] = {
    589		{ .reg = LGDT3305_GEN_CTRL_1,           .val = 0x03, },
    590		{ .reg = 0x000d,                        .val = 0x02, },
    591		{ .reg = 0x000e,                        .val = 0x02, },
    592		{ .reg = LGDT3305_DGTL_AGC_REF_1,       .val = 0x32, },
    593		{ .reg = LGDT3305_DGTL_AGC_REF_2,       .val = 0xc4, },
    594		{ .reg = LGDT3305_CR_CTR_FREQ_1,        .val = 0x00, },
    595		{ .reg = LGDT3305_CR_CTR_FREQ_2,        .val = 0x00, },
    596		{ .reg = LGDT3305_CR_CTR_FREQ_3,        .val = 0x00, },
    597		{ .reg = LGDT3305_CR_CTR_FREQ_4,        .val = 0x00, },
    598		{ .reg = LGDT3305_CR_CTRL_7,            .val = 0xf9, },
    599		{ .reg = 0x0112,                        .val = 0x17, },
    600		{ .reg = 0x0113,                        .val = 0x15, },
    601		{ .reg = 0x0114,                        .val = 0x18, },
    602		{ .reg = 0x0115,                        .val = 0xff, },
    603		{ .reg = 0x0116,                        .val = 0x3c, },
    604		{ .reg = 0x0214,                        .val = 0x67, },
    605		{ .reg = 0x0424,                        .val = 0x8d, },
    606		{ .reg = 0x0427,                        .val = 0x12, },
    607		{ .reg = 0x0428,                        .val = 0x4f, },
    608		{ .reg = LGDT3305_IFBW_1,               .val = 0x80, },
    609		{ .reg = LGDT3305_IFBW_2,               .val = 0x00, },
    610		{ .reg = 0x030a,                        .val = 0x08, },
    611		{ .reg = 0x030b,                        .val = 0x9b, },
    612		{ .reg = 0x030d,                        .val = 0x00, },
    613		{ .reg = 0x030e,                        .val = 0x1c, },
    614		{ .reg = 0x0314,                        .val = 0xe1, },
    615		{ .reg = 0x000d,                        .val = 0x82, },
    616		{ .reg = LGDT3305_TP_CTRL_1,            .val = 0x5b, },
    617		{ .reg = LGDT3305_TP_CTRL_1,            .val = 0x5b, },
    618	};
    619
    620	static struct lgdt3305_reg lgdt3305_init_data[] = {
    621		{ .reg = LGDT3305_GEN_CTRL_1,           .val = 0x03, },
    622		{ .reg = LGDT3305_GEN_CTRL_2,           .val = 0xb0, },
    623		{ .reg = LGDT3305_GEN_CTRL_3,           .val = 0x01, },
    624		{ .reg = LGDT3305_GEN_CONTROL,          .val = 0x6f, },
    625		{ .reg = LGDT3305_GEN_CTRL_4,           .val = 0x03, },
    626		{ .reg = LGDT3305_DGTL_AGC_REF_1,       .val = 0x32, },
    627		{ .reg = LGDT3305_DGTL_AGC_REF_2,       .val = 0xc4, },
    628		{ .reg = LGDT3305_CR_CTR_FREQ_1,        .val = 0x00, },
    629		{ .reg = LGDT3305_CR_CTR_FREQ_2,        .val = 0x00, },
    630		{ .reg = LGDT3305_CR_CTR_FREQ_3,        .val = 0x00, },
    631		{ .reg = LGDT3305_CR_CTR_FREQ_4,        .val = 0x00, },
    632		{ .reg = LGDT3305_CR_CTRL_7,            .val = 0x79, },
    633		{ .reg = LGDT3305_AGC_POWER_REF_1,      .val = 0x32, },
    634		{ .reg = LGDT3305_AGC_POWER_REF_2,      .val = 0xc4, },
    635		{ .reg = LGDT3305_AGC_DELAY_PT_1,       .val = 0x0d, },
    636		{ .reg = LGDT3305_AGC_DELAY_PT_2,       .val = 0x30, },
    637		{ .reg = LGDT3305_RFAGC_LOOP_FLTR_BW_1, .val = 0x80, },
    638		{ .reg = LGDT3305_RFAGC_LOOP_FLTR_BW_2, .val = 0x00, },
    639		{ .reg = LGDT3305_IFBW_1,               .val = 0x80, },
    640		{ .reg = LGDT3305_IFBW_2,               .val = 0x00, },
    641		{ .reg = LGDT3305_AGC_CTRL_1,           .val = 0x30, },
    642		{ .reg = LGDT3305_AGC_CTRL_4,           .val = 0x61, },
    643		{ .reg = LGDT3305_FEC_BLOCK_CTRL,       .val = 0xff, },
    644		{ .reg = LGDT3305_TP_CTRL_1,            .val = 0x1b, },
    645	};
    646
    647	lg_dbg("\n");
    648
    649	switch (state->cfg->demod_chip) {
    650	case LGDT3304:
    651		ret = lgdt3305_write_regs(state, lgdt3304_init_data,
    652					  ARRAY_SIZE(lgdt3304_init_data));
    653		break;
    654	case LGDT3305:
    655		ret = lgdt3305_write_regs(state, lgdt3305_init_data,
    656					  ARRAY_SIZE(lgdt3305_init_data));
    657		break;
    658	default:
    659		ret = -EINVAL;
    660	}
    661	if (lg_fail(ret))
    662		goto fail;
    663
    664	ret = lgdt3305_soft_reset(state);
    665fail:
    666	return ret;
    667}
    668
    669static int lgdt3304_set_parameters(struct dvb_frontend *fe)
    670{
    671	struct dtv_frontend_properties *p = &fe->dtv_property_cache;
    672	struct lgdt3305_state *state = fe->demodulator_priv;
    673	int ret;
    674
    675	lg_dbg("(%d, %d)\n", p->frequency, p->modulation);
    676
    677	if (fe->ops.tuner_ops.set_params) {
    678		ret = fe->ops.tuner_ops.set_params(fe);
    679		if (fe->ops.i2c_gate_ctrl)
    680			fe->ops.i2c_gate_ctrl(fe, 0);
    681		if (lg_fail(ret))
    682			goto fail;
    683		state->current_frequency = p->frequency;
    684	}
    685
    686	ret = lgdt3305_set_modulation(state, p);
    687	if (lg_fail(ret))
    688		goto fail;
    689
    690	ret = lgdt3305_passband_digital_agc(state, p);
    691	if (lg_fail(ret))
    692		goto fail;
    693
    694	ret = lgdt3305_agc_setup(state, p);
    695	if (lg_fail(ret))
    696		goto fail;
    697
    698	/* reg 0x030d is 3304-only... seen in vsb and qam usbsnoops... */
    699	switch (p->modulation) {
    700	case VSB_8:
    701		lgdt3305_write_reg(state, 0x030d, 0x00);
    702		lgdt3305_write_reg(state, LGDT3305_CR_CTR_FREQ_1, 0x4f);
    703		lgdt3305_write_reg(state, LGDT3305_CR_CTR_FREQ_2, 0x0c);
    704		lgdt3305_write_reg(state, LGDT3305_CR_CTR_FREQ_3, 0xac);
    705		lgdt3305_write_reg(state, LGDT3305_CR_CTR_FREQ_4, 0xba);
    706		break;
    707	case QAM_64:
    708	case QAM_256:
    709		lgdt3305_write_reg(state, 0x030d, 0x14);
    710		ret = lgdt3305_set_if(state, p);
    711		if (lg_fail(ret))
    712			goto fail;
    713		break;
    714	default:
    715		return -EINVAL;
    716	}
    717
    718
    719	ret = lgdt3305_spectral_inversion(state, p,
    720					  state->cfg->spectral_inversion
    721					  ? 1 : 0);
    722	if (lg_fail(ret))
    723		goto fail;
    724
    725	state->current_modulation = p->modulation;
    726
    727	ret = lgdt3305_mpeg_mode(state, state->cfg->mpeg_mode);
    728	if (lg_fail(ret))
    729		goto fail;
    730
    731	/* lgdt3305_mpeg_mode_polarity calls lgdt3305_soft_reset */
    732	ret = lgdt3305_mpeg_mode_polarity(state);
    733fail:
    734	return ret;
    735}
    736
    737static int lgdt3305_set_parameters(struct dvb_frontend *fe)
    738{
    739	struct dtv_frontend_properties *p = &fe->dtv_property_cache;
    740	struct lgdt3305_state *state = fe->demodulator_priv;
    741	int ret;
    742
    743	lg_dbg("(%d, %d)\n", p->frequency, p->modulation);
    744
    745	if (fe->ops.tuner_ops.set_params) {
    746		ret = fe->ops.tuner_ops.set_params(fe);
    747		if (fe->ops.i2c_gate_ctrl)
    748			fe->ops.i2c_gate_ctrl(fe, 0);
    749		if (lg_fail(ret))
    750			goto fail;
    751		state->current_frequency = p->frequency;
    752	}
    753
    754	ret = lgdt3305_set_modulation(state, p);
    755	if (lg_fail(ret))
    756		goto fail;
    757
    758	ret = lgdt3305_passband_digital_agc(state, p);
    759	if (lg_fail(ret))
    760		goto fail;
    761	ret = lgdt3305_set_agc_power_ref(state, p);
    762	if (lg_fail(ret))
    763		goto fail;
    764	ret = lgdt3305_agc_setup(state, p);
    765	if (lg_fail(ret))
    766		goto fail;
    767
    768	/* low if */
    769	ret = lgdt3305_write_reg(state, LGDT3305_GEN_CONTROL, 0x2f);
    770	if (lg_fail(ret))
    771		goto fail;
    772	ret = lgdt3305_set_reg_bit(state, LGDT3305_CR_CTR_FREQ_1, 6, 1);
    773	if (lg_fail(ret))
    774		goto fail;
    775
    776	ret = lgdt3305_set_if(state, p);
    777	if (lg_fail(ret))
    778		goto fail;
    779	ret = lgdt3305_spectral_inversion(state, p,
    780					  state->cfg->spectral_inversion
    781					  ? 1 : 0);
    782	if (lg_fail(ret))
    783		goto fail;
    784
    785	ret = lgdt3305_set_filter_extension(state, p);
    786	if (lg_fail(ret))
    787		goto fail;
    788
    789	state->current_modulation = p->modulation;
    790
    791	ret = lgdt3305_mpeg_mode(state, state->cfg->mpeg_mode);
    792	if (lg_fail(ret))
    793		goto fail;
    794
    795	/* lgdt3305_mpeg_mode_polarity calls lgdt3305_soft_reset */
    796	ret = lgdt3305_mpeg_mode_polarity(state);
    797fail:
    798	return ret;
    799}
    800
    801static int lgdt3305_get_frontend(struct dvb_frontend *fe,
    802				 struct dtv_frontend_properties *p)
    803{
    804	struct lgdt3305_state *state = fe->demodulator_priv;
    805
    806	lg_dbg("\n");
    807
    808	p->modulation = state->current_modulation;
    809	p->frequency = state->current_frequency;
    810	return 0;
    811}
    812
    813/* ------------------------------------------------------------------------ */
    814
    815static int lgdt3305_read_cr_lock_status(struct lgdt3305_state *state,
    816					int *locked)
    817{
    818	u8 val;
    819	int ret;
    820	char *cr_lock_state = "";
    821
    822	*locked = 0;
    823
    824	ret = lgdt3305_read_reg(state, LGDT3305_CR_LOCK_STATUS, &val);
    825	if (lg_fail(ret))
    826		goto fail;
    827
    828	switch (state->current_modulation) {
    829	case QAM_256:
    830	case QAM_64:
    831		if (val & (1 << 1))
    832			*locked = 1;
    833
    834		switch (val & 0x07) {
    835		case 0:
    836			cr_lock_state = "QAM UNLOCK";
    837			break;
    838		case 4:
    839			cr_lock_state = "QAM 1stLock";
    840			break;
    841		case 6:
    842			cr_lock_state = "QAM 2ndLock";
    843			break;
    844		case 7:
    845			cr_lock_state = "QAM FinalLock";
    846			break;
    847		default:
    848			cr_lock_state = "CLOCKQAM-INVALID!";
    849			break;
    850		}
    851		break;
    852	case VSB_8:
    853		if (val & (1 << 7)) {
    854			*locked = 1;
    855			cr_lock_state = "CLOCKVSB";
    856		}
    857		break;
    858	default:
    859		ret = -EINVAL;
    860	}
    861	lg_dbg("(%d) %s\n", *locked, cr_lock_state);
    862fail:
    863	return ret;
    864}
    865
    866static int lgdt3305_read_fec_lock_status(struct lgdt3305_state *state,
    867					 int *locked)
    868{
    869	u8 val;
    870	int ret, mpeg_lock, fec_lock, viterbi_lock;
    871
    872	*locked = 0;
    873
    874	switch (state->current_modulation) {
    875	case QAM_256:
    876	case QAM_64:
    877		ret = lgdt3305_read_reg(state,
    878					LGDT3305_FEC_LOCK_STATUS, &val);
    879		if (lg_fail(ret))
    880			goto fail;
    881
    882		mpeg_lock    = (val & (1 << 0)) ? 1 : 0;
    883		fec_lock     = (val & (1 << 2)) ? 1 : 0;
    884		viterbi_lock = (val & (1 << 3)) ? 1 : 0;
    885
    886		*locked = mpeg_lock && fec_lock && viterbi_lock;
    887
    888		lg_dbg("(%d) %s%s%s\n", *locked,
    889		       mpeg_lock    ? "mpeg lock  "  : "",
    890		       fec_lock     ? "fec lock  "   : "",
    891		       viterbi_lock ? "viterbi lock" : "");
    892		break;
    893	case VSB_8:
    894	default:
    895		ret = -EINVAL;
    896	}
    897fail:
    898	return ret;
    899}
    900
    901static int lgdt3305_read_status(struct dvb_frontend *fe, enum fe_status *status)
    902{
    903	struct lgdt3305_state *state = fe->demodulator_priv;
    904	u8 val;
    905	int ret, signal, inlock, nofecerr, snrgood,
    906		cr_lock, fec_lock, sync_lock;
    907
    908	*status = 0;
    909
    910	ret = lgdt3305_read_reg(state, LGDT3305_GEN_STATUS, &val);
    911	if (lg_fail(ret))
    912		goto fail;
    913
    914	signal    = (val & (1 << 4)) ? 1 : 0;
    915	inlock    = (val & (1 << 3)) ? 0 : 1;
    916	sync_lock = (val & (1 << 2)) ? 1 : 0;
    917	nofecerr  = (val & (1 << 1)) ? 1 : 0;
    918	snrgood   = (val & (1 << 0)) ? 1 : 0;
    919
    920	lg_dbg("%s%s%s%s%s\n",
    921	       signal    ? "SIGNALEXIST " : "",
    922	       inlock    ? "INLOCK "      : "",
    923	       sync_lock ? "SYNCLOCK "    : "",
    924	       nofecerr  ? "NOFECERR "    : "",
    925	       snrgood   ? "SNRGOOD "     : "");
    926
    927	ret = lgdt3305_read_cr_lock_status(state, &cr_lock);
    928	if (lg_fail(ret))
    929		goto fail;
    930
    931	if (signal)
    932		*status |= FE_HAS_SIGNAL;
    933	if (cr_lock)
    934		*status |= FE_HAS_CARRIER;
    935	if (nofecerr)
    936		*status |= FE_HAS_VITERBI;
    937	if (sync_lock)
    938		*status |= FE_HAS_SYNC;
    939
    940	switch (state->current_modulation) {
    941	case QAM_256:
    942	case QAM_64:
    943		/* signal bit is unreliable on the DT3304 in QAM mode */
    944		if (((LGDT3304 == state->cfg->demod_chip)) && (cr_lock))
    945			*status |= FE_HAS_SIGNAL;
    946
    947		ret = lgdt3305_read_fec_lock_status(state, &fec_lock);
    948		if (lg_fail(ret))
    949			goto fail;
    950
    951		if (fec_lock)
    952			*status |= FE_HAS_LOCK;
    953		break;
    954	case VSB_8:
    955		if (inlock)
    956			*status |= FE_HAS_LOCK;
    957		break;
    958	default:
    959		ret = -EINVAL;
    960	}
    961fail:
    962	return ret;
    963}
    964
    965/* ------------------------------------------------------------------------ */
    966
    967/* borrowed from lgdt330x.c */
    968static u32 calculate_snr(u32 mse, u32 c)
    969{
    970	if (mse == 0) /* no signal */
    971		return 0;
    972
    973	mse = intlog10(mse);
    974	if (mse > c) {
    975		/* Negative SNR, which is possible, but realisticly the
    976		demod will lose lock before the signal gets this bad.  The
    977		API only allows for unsigned values, so just return 0 */
    978		return 0;
    979	}
    980	return 10*(c - mse);
    981}
    982
    983static int lgdt3305_read_snr(struct dvb_frontend *fe, u16 *snr)
    984{
    985	struct lgdt3305_state *state = fe->demodulator_priv;
    986	u32 noise;	/* noise value */
    987	u32 c;		/* per-modulation SNR calculation constant */
    988
    989	switch (state->current_modulation) {
    990	case VSB_8:
    991#ifdef USE_PTMSE
    992		/* Use Phase Tracker Mean-Square Error Register */
    993		/* SNR for ranges from -13.11 to +44.08 */
    994		noise =	((read_reg(state, LGDT3305_PT_MSE_1) & 0x07) << 16) |
    995			(read_reg(state, LGDT3305_PT_MSE_2) << 8) |
    996			(read_reg(state, LGDT3305_PT_MSE_3) & 0xff);
    997		c = 73957994; /* log10(25*32^2)*2^24 */
    998#else
    999		/* Use Equalizer Mean-Square Error Register */
   1000		/* SNR for ranges from -16.12 to +44.08 */
   1001		noise =	((read_reg(state, LGDT3305_EQ_MSE_1) & 0x0f) << 16) |
   1002			(read_reg(state, LGDT3305_EQ_MSE_2) << 8) |
   1003			(read_reg(state, LGDT3305_EQ_MSE_3) & 0xff);
   1004		c = 73957994; /* log10(25*32^2)*2^24 */
   1005#endif
   1006		break;
   1007	case QAM_64:
   1008	case QAM_256:
   1009		noise = (read_reg(state, LGDT3305_CR_MSE_1) << 8) |
   1010			(read_reg(state, LGDT3305_CR_MSE_2) & 0xff);
   1011
   1012		c = (state->current_modulation == QAM_64) ?
   1013			97939837 : 98026066;
   1014		/* log10(688128)*2^24 and log10(696320)*2^24 */
   1015		break;
   1016	default:
   1017		return -EINVAL;
   1018	}
   1019	state->snr = calculate_snr(noise, c);
   1020	/* report SNR in dB * 10 */
   1021	*snr = (state->snr / ((1 << 24) / 10));
   1022	lg_dbg("noise = 0x%08x, snr = %d.%02d dB\n", noise,
   1023	       state->snr >> 24, (((state->snr >> 8) & 0xffff) * 100) >> 16);
   1024
   1025	return 0;
   1026}
   1027
   1028static int lgdt3305_read_signal_strength(struct dvb_frontend *fe,
   1029					 u16 *strength)
   1030{
   1031	/* borrowed from lgdt330x.c
   1032	 *
   1033	 * Calculate strength from SNR up to 35dB
   1034	 * Even though the SNR can go higher than 35dB,
   1035	 * there is some comfort factor in having a range of
   1036	 * strong signals that can show at 100%
   1037	 */
   1038	struct lgdt3305_state *state = fe->demodulator_priv;
   1039	u16 snr;
   1040	int ret;
   1041
   1042	*strength = 0;
   1043
   1044	ret = fe->ops.read_snr(fe, &snr);
   1045	if (lg_fail(ret))
   1046		goto fail;
   1047	/* Rather than use the 8.8 value snr, use state->snr which is 8.24 */
   1048	/* scale the range 0 - 35*2^24 into 0 - 65535 */
   1049	if (state->snr >= 8960 * 0x10000)
   1050		*strength = 0xffff;
   1051	else
   1052		*strength = state->snr / 8960;
   1053fail:
   1054	return ret;
   1055}
   1056
   1057/* ------------------------------------------------------------------------ */
   1058
   1059static int lgdt3305_read_ber(struct dvb_frontend *fe, u32 *ber)
   1060{
   1061	*ber = 0;
   1062	return 0;
   1063}
   1064
   1065static int lgdt3305_read_ucblocks(struct dvb_frontend *fe, u32 *ucblocks)
   1066{
   1067	struct lgdt3305_state *state = fe->demodulator_priv;
   1068
   1069	*ucblocks =
   1070		(read_reg(state, LGDT3305_FEC_PKT_ERR_1) << 8) |
   1071		(read_reg(state, LGDT3305_FEC_PKT_ERR_2) & 0xff);
   1072
   1073	return 0;
   1074}
   1075
   1076static int lgdt3305_get_tune_settings(struct dvb_frontend *fe,
   1077				      struct dvb_frontend_tune_settings
   1078					*fe_tune_settings)
   1079{
   1080	fe_tune_settings->min_delay_ms = 500;
   1081	lg_dbg("\n");
   1082	return 0;
   1083}
   1084
   1085static void lgdt3305_release(struct dvb_frontend *fe)
   1086{
   1087	struct lgdt3305_state *state = fe->demodulator_priv;
   1088	lg_dbg("\n");
   1089	kfree(state);
   1090}
   1091
   1092static const struct dvb_frontend_ops lgdt3304_ops;
   1093static const struct dvb_frontend_ops lgdt3305_ops;
   1094
   1095struct dvb_frontend *lgdt3305_attach(const struct lgdt3305_config *config,
   1096				     struct i2c_adapter *i2c_adap)
   1097{
   1098	struct lgdt3305_state *state = NULL;
   1099	int ret;
   1100	u8 val;
   1101
   1102	lg_dbg("(%d-%04x)\n",
   1103	       i2c_adap ? i2c_adapter_id(i2c_adap) : 0,
   1104	       config ? config->i2c_addr : 0);
   1105
   1106	state = kzalloc(sizeof(struct lgdt3305_state), GFP_KERNEL);
   1107	if (state == NULL)
   1108		goto fail;
   1109
   1110	state->cfg = config;
   1111	state->i2c_adap = i2c_adap;
   1112
   1113	switch (config->demod_chip) {
   1114	case LGDT3304:
   1115		memcpy(&state->frontend.ops, &lgdt3304_ops,
   1116		       sizeof(struct dvb_frontend_ops));
   1117		break;
   1118	case LGDT3305:
   1119		memcpy(&state->frontend.ops, &lgdt3305_ops,
   1120		       sizeof(struct dvb_frontend_ops));
   1121		break;
   1122	default:
   1123		goto fail;
   1124	}
   1125	state->frontend.demodulator_priv = state;
   1126
   1127	/* verify that we're talking to a lg dt3304/5 */
   1128	ret = lgdt3305_read_reg(state, LGDT3305_GEN_CTRL_2, &val);
   1129	if ((lg_fail(ret)) | (val == 0))
   1130		goto fail;
   1131	ret = lgdt3305_write_reg(state, 0x0808, 0x80);
   1132	if (lg_fail(ret))
   1133		goto fail;
   1134	ret = lgdt3305_read_reg(state, 0x0808, &val);
   1135	if ((lg_fail(ret)) | (val != 0x80))
   1136		goto fail;
   1137	ret = lgdt3305_write_reg(state, 0x0808, 0x00);
   1138	if (lg_fail(ret))
   1139		goto fail;
   1140
   1141	state->current_frequency = -1;
   1142	state->current_modulation = -1;
   1143
   1144	return &state->frontend;
   1145fail:
   1146	lg_warn("unable to detect %s hardware\n",
   1147		config->demod_chip ? "LGDT3304" : "LGDT3305");
   1148	kfree(state);
   1149	return NULL;
   1150}
   1151EXPORT_SYMBOL(lgdt3305_attach);
   1152
   1153static const struct dvb_frontend_ops lgdt3304_ops = {
   1154	.delsys = { SYS_ATSC, SYS_DVBC_ANNEX_B },
   1155	.info = {
   1156		.name = "LG Electronics LGDT3304 VSB/QAM Frontend",
   1157		.frequency_min_hz      =  54 * MHz,
   1158		.frequency_max_hz      = 858 * MHz,
   1159		.frequency_stepsize_hz = 62500,
   1160		.caps = FE_CAN_QAM_64 | FE_CAN_QAM_256 | FE_CAN_8VSB
   1161	},
   1162	.i2c_gate_ctrl        = lgdt3305_i2c_gate_ctrl,
   1163	.init                 = lgdt3305_init,
   1164	.sleep                = lgdt3305_sleep,
   1165	.set_frontend         = lgdt3304_set_parameters,
   1166	.get_frontend         = lgdt3305_get_frontend,
   1167	.get_tune_settings    = lgdt3305_get_tune_settings,
   1168	.read_status          = lgdt3305_read_status,
   1169	.read_ber             = lgdt3305_read_ber,
   1170	.read_signal_strength = lgdt3305_read_signal_strength,
   1171	.read_snr             = lgdt3305_read_snr,
   1172	.read_ucblocks        = lgdt3305_read_ucblocks,
   1173	.release              = lgdt3305_release,
   1174};
   1175
   1176static const struct dvb_frontend_ops lgdt3305_ops = {
   1177	.delsys = { SYS_ATSC, SYS_DVBC_ANNEX_B },
   1178	.info = {
   1179		.name = "LG Electronics LGDT3305 VSB/QAM Frontend",
   1180		.frequency_min_hz      =  54 * MHz,
   1181		.frequency_max_hz      = 858 * MHz,
   1182		.frequency_stepsize_hz = 62500,
   1183		.caps = FE_CAN_QAM_64 | FE_CAN_QAM_256 | FE_CAN_8VSB
   1184	},
   1185	.i2c_gate_ctrl        = lgdt3305_i2c_gate_ctrl,
   1186	.init                 = lgdt3305_init,
   1187	.sleep                = lgdt3305_sleep,
   1188	.set_frontend         = lgdt3305_set_parameters,
   1189	.get_frontend         = lgdt3305_get_frontend,
   1190	.get_tune_settings    = lgdt3305_get_tune_settings,
   1191	.read_status          = lgdt3305_read_status,
   1192	.read_ber             = lgdt3305_read_ber,
   1193	.read_signal_strength = lgdt3305_read_signal_strength,
   1194	.read_snr             = lgdt3305_read_snr,
   1195	.read_ucblocks        = lgdt3305_read_ucblocks,
   1196	.release              = lgdt3305_release,
   1197};
   1198
   1199MODULE_DESCRIPTION("LG Electronics LGDT3304/5 ATSC/QAM-B Demodulator Driver");
   1200MODULE_AUTHOR("Michael Krufky <mkrufky@linuxtv.org>");
   1201MODULE_LICENSE("GPL");
   1202MODULE_VERSION("0.2");