Jesse Keating 2f82dda
From b71e18093e2e7f240797875c50c49552722f8825 Mon Sep 17 00:00:00 2001
Jesse Keating 2f82dda
From: Jarod Wilson <jarod@redhat.com>
Jesse Keating 2f82dda
Date: Mon, 15 Feb 2010 17:13:25 -0500
Jesse Keating 2f82dda
Subject: [PATCH 1/2] dvb: add lgdt3304 support to lgdt3305 driver
Jesse Keating 2f82dda
Jesse Keating 2f82dda
There's a currently-unused lgdt3304 demod driver, which leaves a lot to
Jesse Keating 2f82dda
be desired as far as functionality. The 3304 is unsurprisingly quite
Jesse Keating 2f82dda
similar to the 3305, and empirical testing yeilds far better results
Jesse Keating 2f82dda
and more complete functionality by merging 3304 support into the 3305
Jesse Keating 2f82dda
driver. (For example, the current lgdt3304 driver lacks support for
Jesse Keating 2f82dda
signal strength, snr, ucblocks, etc., which we get w/the lgdt3305).
Jesse Keating 2f82dda
Jesse Keating 2f82dda
For the moment, not dropping the lgdt3304 driver, and its still up to
Jesse Keating 2f82dda
a given device's config setup to choose which demod driver to use, but
Jesse Keating 2f82dda
I'd suggest dropping the 3304 driver entirely.
Jesse Keating 2f82dda
Jesse Keating 2f82dda
As a follow-up to this patch, I've got another patch that adds support
Jesse Keating 2f82dda
for the KWorld PlusTV 340U (ATSC) em2870-based tuner stick, driving
Jesse Keating 2f82dda
its lgdt3304 demod via this lgdt3305 driver, which is what I used to
Jesse Keating 2f82dda
successfully test this patch with both VSB_8 and QAM_256 signals.
Jesse Keating 2f82dda
Jesse Keating 2f82dda
A few pieces are still a touch crude, but I think its a solid start,
Jesse Keating 2f82dda
as well as much cleaner and more feature-complete than the existing
Jesse Keating 2f82dda
lgdt3304 driver.
Jesse Keating 2f82dda
Jesse Keating 2f82dda
Signed-off-by: Jarod Wilson <jarod@redhat.com>
Jesse Keating 2f82dda
---
Jesse Keating 2f82dda
 drivers/media/dvb/frontends/lgdt3305.c |  206 ++++++++++++++++++++++++++++++--
Jesse Keating 2f82dda
 drivers/media/dvb/frontends/lgdt3305.h |    6 +
Jesse Keating 2f82dda
 2 files changed, 203 insertions(+), 9 deletions(-)
Jesse Keating 2f82dda
Jesse Keating 2f82dda
diff --git a/drivers/media/dvb/frontends/lgdt3305.c b/drivers/media/dvb/frontends/lgdt3305.c
Jesse Keating 2f82dda
index fde8c59..40695e6 100644
Jesse Keating 2f82dda
--- a/drivers/media/dvb/frontends/lgdt3305.c
Jesse Keating 2f82dda
+++ b/drivers/media/dvb/frontends/lgdt3305.c
Jesse Keating 2f82dda
@@ -1,5 +1,5 @@
Jesse Keating 2f82dda
 /*
Jesse Keating 2f82dda
- *    Support for LGDT3305 - VSB/QAM
Jesse Keating 2f82dda
+ *    Support for LG Electronics LGDT3304 and LGDT3305 - VSB/QAM
Jesse Keating 2f82dda
  *
Jesse Keating 2f82dda
  *    Copyright (C) 2008, 2009 Michael Krufky <mkrufky@linuxtv.org>
Jesse Keating 2f82dda
  *
Jesse Keating 2f82dda
@@ -357,7 +357,10 @@ static int lgdt3305_rfagc_loop(struct lgdt3305_state *state,
Jesse Keating 2f82dda
 	case QAM_256:
Jesse Keating 2f82dda
 		agcdelay = 0x046b;
Jesse Keating 2f82dda
 		rfbw     = 0x8889;
Jesse Keating 2f82dda
-		ifbw     = 0x8888;
Jesse Keating 2f82dda
+		if (state->cfg->demod_chip == LGDT3305)
Jesse Keating 2f82dda
+			ifbw = 0x8888;
Jesse Keating 2f82dda
+		else
Jesse Keating 2f82dda
+			ifbw = 0x6666;
Jesse Keating 2f82dda
 		break;
Jesse Keating 2f82dda
 	default:
Jesse Keating 2f82dda
 		return -EINVAL;
Jesse Keating 2f82dda
@@ -409,8 +412,18 @@ static int lgdt3305_agc_setup(struct lgdt3305_state *state,
Jesse Keating 2f82dda
 	lg_dbg("lockdten = %d, acqen = %d\n", lockdten, acqen);
Jesse Keating 2f82dda
 
Jesse Keating 2f82dda
 	/* control agc function */
Jesse Keating 2f82dda
-	lgdt3305_write_reg(state, LGDT3305_AGC_CTRL_4, 0xe1 | lockdten << 1);
Jesse Keating 2f82dda
-	lgdt3305_set_reg_bit(state, LGDT3305_AGC_CTRL_1, 2, acqen);
Jesse Keating 2f82dda
+	switch (state->cfg->demod_chip) {
Jesse Keating 2f82dda
+	case LGDT3304:
Jesse Keating 2f82dda
+		lgdt3305_write_reg(state, 0x0314, 0xe1 | lockdten << 1);
Jesse Keating 2f82dda
+		lgdt3305_set_reg_bit(state, 0x030e, 2, acqen);
Jesse Keating 2f82dda
+		break;
Jesse Keating 2f82dda
+	case LGDT3305:
Jesse Keating 2f82dda
+		lgdt3305_write_reg(state, LGDT3305_AGC_CTRL_4, 0xe1 | lockdten << 1);
Jesse Keating 2f82dda
+		lgdt3305_set_reg_bit(state, LGDT3305_AGC_CTRL_1, 2, acqen);
Jesse Keating 2f82dda
+		break;
Jesse Keating 2f82dda
+	default:
Jesse Keating 2f82dda
+		return -EINVAL;
Jesse Keating 2f82dda
+	}
Jesse Keating 2f82dda
 
Jesse Keating 2f82dda
 	return lgdt3305_rfagc_loop(state, param);
Jesse Keating 2f82dda
 }
Jesse Keating 2f82dda
@@ -543,6 +556,11 @@ static int lgdt3305_i2c_gate_ctrl(struct dvb_frontend *fe, int enable)
Jesse Keating 2f82dda
 				    enable ? 0 : 1);
Jesse Keating 2f82dda
 }
Jesse Keating 2f82dda
 
Jesse Keating 2f82dda
+static int lgdt3304_sleep(struct dvb_frontend *fe)
Jesse Keating 2f82dda
+{
Jesse Keating 2f82dda
+	return 0;
Jesse Keating 2f82dda
+}
Jesse Keating 2f82dda
+
Jesse Keating 2f82dda
 static int lgdt3305_sleep(struct dvb_frontend *fe)
Jesse Keating 2f82dda
 {
Jesse Keating 2f82dda
 	struct lgdt3305_state *state = fe->demodulator_priv;
Jesse Keating 2f82dda
@@ -571,6 +589,55 @@ static int lgdt3305_sleep(struct dvb_frontend *fe)
Jesse Keating 2f82dda
 	return 0;
Jesse Keating 2f82dda
 }
Jesse Keating 2f82dda
 
Jesse Keating 2f82dda
+static int lgdt3304_init(struct dvb_frontend *fe)
Jesse Keating 2f82dda
+{
Jesse Keating 2f82dda
+	struct lgdt3305_state *state = fe->demodulator_priv;
Jesse Keating 2f82dda
+	int ret;
Jesse Keating 2f82dda
+
Jesse Keating 2f82dda
+	static struct lgdt3305_reg lgdt3304_init_data[] = {
Jesse Keating 2f82dda
+		{ .reg = LGDT3305_GEN_CTRL_1,     .val = 0x03, },
Jesse Keating 2f82dda
+		{ .reg = 0x000d,                  .val = 0x02, },
Jesse Keating 2f82dda
+		{ .reg = 0x000e,                  .val = 0x02, },
Jesse Keating 2f82dda
+		{ .reg = LGDT3305_DGTL_AGC_REF_1, .val = 0x32, },
Jesse Keating 2f82dda
+		{ .reg = LGDT3305_DGTL_AGC_REF_2, .val = 0xc4, },
Jesse Keating 2f82dda
+		{ .reg = LGDT3305_CR_CTR_FREQ_1,  .val = 0x00, },
Jesse Keating 2f82dda
+		{ .reg = LGDT3305_CR_CTR_FREQ_2,  .val = 0x00, },
Jesse Keating 2f82dda
+		{ .reg = LGDT3305_CR_CTR_FREQ_3,  .val = 0x00, },
Jesse Keating 2f82dda
+		{ .reg = LGDT3305_CR_CTR_FREQ_4,  .val = 0x00, },
Jesse Keating 2f82dda
+		{ .reg = LGDT3305_CR_CTRL_7,      .val = 0xf9, },
Jesse Keating 2f82dda
+		{ .reg = 0x0112,                  .val = 0x17, },
Jesse Keating 2f82dda
+		{ .reg = 0x0113,                  .val = 0x15, },
Jesse Keating 2f82dda
+		{ .reg = 0x0114,                  .val = 0x18, },
Jesse Keating 2f82dda
+		{ .reg = 0x0115,                  .val = 0xff, },
Jesse Keating 2f82dda
+		{ .reg = 0x0116,                  .val = 0x3c, },
Jesse Keating 2f82dda
+		{ .reg = 0x0214,                  .val = 0x67, },
Jesse Keating 2f82dda
+		{ .reg = 0x0424,                  .val = 0x8d, },
Jesse Keating 2f82dda
+		{ .reg = 0x0427,                  .val = 0x12, },
Jesse Keating 2f82dda
+		{ .reg = 0x0428,                  .val = 0x4f, },
Jesse Keating 2f82dda
+		{ .reg = LGDT3305_IFBW_1,         .val = 0x80, },
Jesse Keating 2f82dda
+		{ .reg = LGDT3305_IFBW_2,         .val = 0x00, },
Jesse Keating 2f82dda
+		{ .reg = 0x030a,                  .val = 0x08, },
Jesse Keating 2f82dda
+		{ .reg = 0x030b,                  .val = 0x9b, },
Jesse Keating 2f82dda
+		{ .reg = 0x030d,                  .val = 0x00, },
Jesse Keating 2f82dda
+		{ .reg = 0x030e,                  .val = 0x1c, },
Jesse Keating 2f82dda
+		{ .reg = 0x0314,                  .val = 0xe1, },
Jesse Keating 2f82dda
+		{ .reg = 0x000d,                  .val = 0x82, },
Jesse Keating 2f82dda
+		{ .reg = LGDT3305_TP_CTRL_1,      .val = 0x5b, },
Jesse Keating 2f82dda
+		{ .reg = LGDT3305_TP_CTRL_1,      .val = 0x5b, },
Jesse Keating 2f82dda
+	};
Jesse Keating 2f82dda
+
Jesse Keating 2f82dda
+	lg_dbg("\n");
Jesse Keating 2f82dda
+
Jesse Keating 2f82dda
+	ret = lgdt3305_write_regs(state, lgdt3304_init_data,
Jesse Keating 2f82dda
+				  ARRAY_SIZE(lgdt3304_init_data));
Jesse Keating 2f82dda
+	if (lg_fail(ret))
Jesse Keating 2f82dda
+		goto fail;
Jesse Keating 2f82dda
+
Jesse Keating 2f82dda
+	ret = lgdt3305_soft_reset(state);
Jesse Keating 2f82dda
+fail:
Jesse Keating 2f82dda
+	return ret;
Jesse Keating 2f82dda
+}
Jesse Keating 2f82dda
+
Jesse Keating 2f82dda
 static int lgdt3305_init(struct dvb_frontend *fe)
Jesse Keating 2f82dda
 {
Jesse Keating 2f82dda
 	struct lgdt3305_state *state = fe->demodulator_priv;
Jesse Keating 2f82dda
@@ -639,6 +706,88 @@ fail:
Jesse Keating 2f82dda
 	return ret;
Jesse Keating 2f82dda
 }
Jesse Keating 2f82dda
 
Jesse Keating 2f82dda
+static int lgdt3304_set_parameters(struct dvb_frontend *fe,
Jesse Keating 2f82dda
+				   struct dvb_frontend_parameters *param)
Jesse Keating 2f82dda
+{
Jesse Keating 2f82dda
+	struct lgdt3305_state *state = fe->demodulator_priv;
Jesse Keating 2f82dda
+	int ret;
Jesse Keating 2f82dda
+
Jesse Keating 2f82dda
+	lg_dbg("(%d, %d)\n", param->frequency, param->u.vsb.modulation);
Jesse Keating 2f82dda
+
Jesse Keating 2f82dda
+	if (fe->ops.tuner_ops.set_params) {
Jesse Keating 2f82dda
+		ret = fe->ops.tuner_ops.set_params(fe, param);
Jesse Keating 2f82dda
+		if (fe->ops.i2c_gate_ctrl)
Jesse Keating 2f82dda
+			fe->ops.i2c_gate_ctrl(fe, 0);
Jesse Keating 2f82dda
+		if (lg_fail(ret))
Jesse Keating 2f82dda
+			goto fail;
Jesse Keating 2f82dda
+		state->current_frequency = param->frequency;
Jesse Keating 2f82dda
+	}
Jesse Keating 2f82dda
+
Jesse Keating 2f82dda
+	ret = lgdt3305_set_modulation(state, param);
Jesse Keating 2f82dda
+	if (lg_fail(ret))
Jesse Keating 2f82dda
+		goto fail;
Jesse Keating 2f82dda
+
Jesse Keating 2f82dda
+	ret = lgdt3305_passband_digital_agc(state, param);
Jesse Keating 2f82dda
+	if (lg_fail(ret))
Jesse Keating 2f82dda
+		goto fail;
Jesse Keating 2f82dda
+
Jesse Keating 2f82dda
+	ret = lgdt3305_agc_setup(state, param);
Jesse Keating 2f82dda
+	if (lg_fail(ret))
Jesse Keating 2f82dda
+		goto fail;
Jesse Keating 2f82dda
+
Jesse Keating 2f82dda
+	/* reg 0x030d is 3304-only... seen in vsb and qam usbsnoops... */
Jesse Keating 2f82dda
+	switch (param->u.vsb.modulation) {
Jesse Keating 2f82dda
+	case VSB_8:
Jesse Keating 2f82dda
+		lgdt3305_write_reg(state, 0x030d, 0x00);
Jesse Keating 2f82dda
+#if 1
Jesse Keating 2f82dda
+		lgdt3305_write_reg(state, LGDT3305_CR_CTR_FREQ_1, 0x4f);
Jesse Keating 2f82dda
+		lgdt3305_write_reg(state, LGDT3305_CR_CTR_FREQ_2, 0x0c);
Jesse Keating 2f82dda
+		lgdt3305_write_reg(state, LGDT3305_CR_CTR_FREQ_3, 0xac);
Jesse Keating 2f82dda
+		lgdt3305_write_reg(state, LGDT3305_CR_CTR_FREQ_4, 0xba);
Jesse Keating 2f82dda
+#endif
Jesse Keating 2f82dda
+		break;
Jesse Keating 2f82dda
+	case QAM_64:
Jesse Keating 2f82dda
+	case QAM_256:
Jesse Keating 2f82dda
+		lgdt3305_write_reg(state, 0x030d, 0x14);
Jesse Keating 2f82dda
+#if 1
Jesse Keating 2f82dda
+		ret = lgdt3305_set_if(state, param);
Jesse Keating 2f82dda
+		if (lg_fail(ret))
Jesse Keating 2f82dda
+			goto fail;
Jesse Keating 2f82dda
+#endif
Jesse Keating 2f82dda
+		break;
Jesse Keating 2f82dda
+	default:
Jesse Keating 2f82dda
+		return -EINVAL;
Jesse Keating 2f82dda
+	}
Jesse Keating 2f82dda
+
Jesse Keating 2f82dda
+#if 0
Jesse Keating 2f82dda
+	/* the set_if vsb formula doesn't work for the 3304, we end up sending
Jesse Keating 2f82dda
+	 * 0x40851e07 instead of 0x4f0cacba (which works back to 94050, rather
Jesse Keating 2f82dda
+	 * than 3250, in the case of the kworld 340u) */
Jesse Keating 2f82dda
+	ret = lgdt3305_set_if(state, param);
Jesse Keating 2f82dda
+	if (lg_fail(ret))
Jesse Keating 2f82dda
+		goto fail;
Jesse Keating 2f82dda
+#endif
Jesse Keating 2f82dda
+
Jesse Keating 2f82dda
+	ret = lgdt3305_spectral_inversion(state, param,
Jesse Keating 2f82dda
+					  state->cfg->spectral_inversion
Jesse Keating 2f82dda
+					  ? 1 : 0);
Jesse Keating 2f82dda
+	if (lg_fail(ret))
Jesse Keating 2f82dda
+		goto fail;
Jesse Keating 2f82dda
+
Jesse Keating 2f82dda
+	state->current_modulation = param->u.vsb.modulation;
Jesse Keating 2f82dda
+
Jesse Keating 2f82dda
+	ret = lgdt3305_mpeg_mode(state, state->cfg->mpeg_mode);
Jesse Keating 2f82dda
+	if (lg_fail(ret))
Jesse Keating 2f82dda
+		goto fail;
Jesse Keating 2f82dda
+
Jesse Keating 2f82dda
+	/* lgdt3305_mpeg_mode_polarity calls lgdt3305_soft_reset */
Jesse Keating 2f82dda
+	ret = lgdt3305_mpeg_mode_polarity(state,
Jesse Keating 2f82dda
+					  state->cfg->tpclk_edge,
Jesse Keating 2f82dda
+					  state->cfg->tpvalid_polarity);
Jesse Keating 2f82dda
+fail:
Jesse Keating 2f82dda
+	return ret;
Jesse Keating 2f82dda
+}
Jesse Keating 2f82dda
+
Jesse Keating 2f82dda
 static int lgdt3305_set_parameters(struct dvb_frontend *fe,
Jesse Keating 2f82dda
 				   struct dvb_frontend_parameters *param)
Jesse Keating 2f82dda
 {
Jesse Keating 2f82dda
@@ -847,6 +996,10 @@ static int lgdt3305_read_status(struct dvb_frontend *fe, fe_status_t *status)
Jesse Keating 2f82dda
 	switch (state->current_modulation) {
Jesse Keating 2f82dda
 	case QAM_256:
Jesse Keating 2f82dda
 	case QAM_64:
Jesse Keating 2f82dda
+#if 0 /* needed w/3304 to set FE_HAS_SIGNAL */
Jesse Keating 2f82dda
+		if (cr_lock)
Jesse Keating 2f82dda
+			*status |= FE_HAS_SIGNAL;
Jesse Keating 2f82dda
+#endif
Jesse Keating 2f82dda
 		ret = lgdt3305_read_fec_lock_status(state, &fec_lock);
Jesse Keating 2f82dda
 		if (lg_fail(ret))
Jesse Keating 2f82dda
 			goto fail;
Jesse Keating 2f82dda
@@ -992,6 +1145,7 @@ static void lgdt3305_release(struct dvb_frontend *fe)
Jesse Keating 2f82dda
 	kfree(state);
Jesse Keating 2f82dda
 }
Jesse Keating 2f82dda
 
Jesse Keating 2f82dda
+static struct dvb_frontend_ops lgdt3304_ops;
Jesse Keating 2f82dda
 static struct dvb_frontend_ops lgdt3305_ops;
Jesse Keating 2f82dda
 
Jesse Keating 2f82dda
 struct dvb_frontend *lgdt3305_attach(const struct lgdt3305_config *config,
Jesse Keating 2f82dda
@@ -1012,11 +1166,21 @@ struct dvb_frontend *lgdt3305_attach(const struct lgdt3305_config *config,
Jesse Keating 2f82dda
 	state->cfg = config;
Jesse Keating 2f82dda
 	state->i2c_adap = i2c_adap;
Jesse Keating 2f82dda
 
Jesse Keating 2f82dda
-	memcpy(&state->frontend.ops, &lgdt3305_ops,
Jesse Keating 2f82dda
-	       sizeof(struct dvb_frontend_ops));
Jesse Keating 2f82dda
+	switch (config->demod_chip) {
Jesse Keating 2f82dda
+	case LGDT3304:
Jesse Keating 2f82dda
+		memcpy(&state->frontend.ops, &lgdt3304_ops,
Jesse Keating 2f82dda
+		       sizeof(struct dvb_frontend_ops));
Jesse Keating 2f82dda
+		break;
Jesse Keating 2f82dda
+	case LGDT3305:
Jesse Keating 2f82dda
+		memcpy(&state->frontend.ops, &lgdt3305_ops,
Jesse Keating 2f82dda
+		       sizeof(struct dvb_frontend_ops));
Jesse Keating 2f82dda
+		break;
Jesse Keating 2f82dda
+	default:
Jesse Keating 2f82dda
+		goto fail;
Jesse Keating 2f82dda
+	}
Jesse Keating 2f82dda
 	state->frontend.demodulator_priv = state;
Jesse Keating 2f82dda
 
Jesse Keating 2f82dda
-	/* verify that we're talking to a lg dt3305 */
Jesse Keating 2f82dda
+	/* verify that we're talking to a lg dt3304/5 */
Jesse Keating 2f82dda
 	ret = lgdt3305_read_reg(state, LGDT3305_GEN_CTRL_2, &val;;
Jesse Keating 2f82dda
 	if ((lg_fail(ret)) | (val == 0))
Jesse Keating 2f82dda
 		goto fail;
Jesse Keating 2f82dda
@@ -1035,12 +1199,36 @@ struct dvb_frontend *lgdt3305_attach(const struct lgdt3305_config *config,
Jesse Keating 2f82dda
 
Jesse Keating 2f82dda
 	return &state->frontend;
Jesse Keating 2f82dda
 fail:
Jesse Keating 2f82dda
-	lg_warn("unable to detect LGDT3305 hardware\n");
Jesse Keating 2f82dda
+	lg_warn("unable to detect %s hardware\n",
Jesse Keating 2f82dda
+		config->demod_chip ? "LGDT3304" : "LGDT3305");
Jesse Keating 2f82dda
 	kfree(state);
Jesse Keating 2f82dda
 	return NULL;
Jesse Keating 2f82dda
 }
Jesse Keating 2f82dda
 EXPORT_SYMBOL(lgdt3305_attach);
Jesse Keating 2f82dda
 
Jesse Keating 2f82dda
+static struct dvb_frontend_ops lgdt3304_ops = {
Jesse Keating 2f82dda
+	.info = {
Jesse Keating 2f82dda
+		.name = "LG Electronics LGDT3304 VSB/QAM Frontend",
Jesse Keating 2f82dda
+		.type               = FE_ATSC,
Jesse Keating 2f82dda
+		.frequency_min      = 54000000,
Jesse Keating 2f82dda
+		.frequency_max      = 858000000,
Jesse Keating 2f82dda
+		.frequency_stepsize = 62500,
Jesse Keating 2f82dda
+		.caps = FE_CAN_QAM_64 | FE_CAN_QAM_256 | FE_CAN_8VSB
Jesse Keating 2f82dda
+	},
Jesse Keating 2f82dda
+	.i2c_gate_ctrl        = lgdt3305_i2c_gate_ctrl,
Jesse Keating 2f82dda
+	.init                 = lgdt3304_init,
Jesse Keating 2f82dda
+	.sleep                = lgdt3304_sleep,
Jesse Keating 2f82dda
+	.set_frontend         = lgdt3304_set_parameters,
Jesse Keating 2f82dda
+	.get_frontend         = lgdt3305_get_frontend,
Jesse Keating 2f82dda
+	.get_tune_settings    = lgdt3305_get_tune_settings,
Jesse Keating 2f82dda
+	.read_status          = lgdt3305_read_status,
Jesse Keating 2f82dda
+	.read_ber             = lgdt3305_read_ber,
Jesse Keating 2f82dda
+	.read_signal_strength = lgdt3305_read_signal_strength,
Jesse Keating 2f82dda
+	.read_snr             = lgdt3305_read_snr,
Jesse Keating 2f82dda
+	.read_ucblocks        = lgdt3305_read_ucblocks,
Jesse Keating 2f82dda
+	.release              = lgdt3305_release,
Jesse Keating 2f82dda
+};
Jesse Keating 2f82dda
+
Jesse Keating 2f82dda
 static struct dvb_frontend_ops lgdt3305_ops = {
Jesse Keating 2f82dda
 	.info = {
Jesse Keating 2f82dda
 		.name = "LG Electronics LGDT3305 VSB/QAM Frontend",
Jesse Keating 2f82dda
@@ -1064,7 +1252,7 @@ static struct dvb_frontend_ops lgdt3305_ops = {
Jesse Keating 2f82dda
 	.release              = lgdt3305_release,
Jesse Keating 2f82dda
 };
Jesse Keating 2f82dda
 
Jesse Keating 2f82dda
-MODULE_DESCRIPTION("LG Electronics LGDT3305 ATSC/QAM-B Demodulator Driver");
Jesse Keating 2f82dda
+MODULE_DESCRIPTION("LG Electronics LGDT3304/5 ATSC/QAM-B Demodulator Driver");
Jesse Keating 2f82dda
 MODULE_AUTHOR("Michael Krufky <mkrufky@linuxtv.org>");
Jesse Keating 2f82dda
 MODULE_LICENSE("GPL");
Jesse Keating 2f82dda
 MODULE_VERSION("0.1");
Jesse Keating 2f82dda
diff --git a/drivers/media/dvb/frontends/lgdt3305.h b/drivers/media/dvb/frontends/lgdt3305.h
Jesse Keating 2f82dda
index 9cb11c9..a7f30c2 100644
Jesse Keating 2f82dda
--- a/drivers/media/dvb/frontends/lgdt3305.h
Jesse Keating 2f82dda
+++ b/drivers/media/dvb/frontends/lgdt3305.h
Jesse Keating 2f82dda
@@ -41,6 +41,11 @@ enum lgdt3305_tp_valid_polarity {
Jesse Keating 2f82dda
 	LGDT3305_TP_VALID_HIGH = 1,
Jesse Keating 2f82dda
 };
Jesse Keating 2f82dda
 
Jesse Keating 2f82dda
+enum lgdt_demod_chip_type {
Jesse Keating 2f82dda
+	LGDT3305 = 0,
Jesse Keating 2f82dda
+	LGDT3304 = 1,
Jesse Keating 2f82dda
+};
Jesse Keating 2f82dda
+
Jesse Keating 2f82dda
 struct lgdt3305_config {
Jesse Keating 2f82dda
 	u8 i2c_addr;
Jesse Keating 2f82dda
 
Jesse Keating 2f82dda
@@ -65,6 +70,7 @@ struct lgdt3305_config {
Jesse Keating 2f82dda
 	enum lgdt3305_mpeg_mode mpeg_mode;
Jesse Keating 2f82dda
 	enum lgdt3305_tp_clock_edge tpclk_edge;
Jesse Keating 2f82dda
 	enum lgdt3305_tp_valid_polarity tpvalid_polarity;
Jesse Keating 2f82dda
+	enum lgdt_demod_chip_type demod_chip;
Jesse Keating 2f82dda
 };
Jesse Keating 2f82dda
 
Jesse Keating 2f82dda
 #if defined(CONFIG_DVB_LGDT3305) || (defined(CONFIG_DVB_LGDT3305_MODULE) && \
Jesse Keating 2f82dda
-- 
Jesse Keating 2f82dda
1.6.6
Jesse Keating 2f82dda