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