File Index
Files and directories
Sign in
FILE

lgdt3305.c

File preview with syntax highlighting.

linux-6.19.14/drivers/media/dvb-frontends/lgdt3305.c C
   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 <linux/int_log.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_GPL(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");
~/ Read-only file preview.