diff mbox

add support for the dvb-t part of CT-3650

Message ID 201106070205.08118.jareguero@telefonica.net (mailing list archive)
State Superseded
Headers show

Commit Message

Jose Alberto Reguero June 7, 2011, 12:05 a.m. UTC
This patch add suport for the dvb-t part of CT-3650.

Jose Alberto

Signed-off-by: Jose Alberto Reguero <jareguero@telefonica.net>
diff mbox

Patch

diff -urN linux/drivers/media/common/tuners/tda827x.c linux.new/drivers/media/common/tuners/tda827x.c
--- linux/drivers/media/common/tuners/tda827x.c	2010-07-03 23:22:08.000000000 +0200
+++ linux.new/drivers/media/common/tuners/tda827x.c	2011-06-06 14:45:02.912154000 +0200
@@ -135,14 +135,29 @@ 
 
 static int tuner_transfer(struct dvb_frontend *fe,
 			  struct i2c_msg *msg,
-			  const int size)
+			  int size)
 {
 	int rc;
 	struct tda827x_priv *priv = fe->tuner_priv;
+	struct i2c_msg msgr[2];
 
 	if (fe->ops.i2c_gate_ctrl)
 		fe->ops.i2c_gate_ctrl(fe, 1);
-	rc = i2c_transfer(priv->i2c_adap, msg, size);
+	if (priv->cfg->i2cr && (msg->flags == I2C_M_RD)) {
+		msgr[0].addr = msg->addr;
+		msgr[0].flags = 0;
+		msgr[0].len = msg->len - 1;
+		msgr[0].buf = msg->buf;
+		msgr[1].addr = msg->addr;
+		msgr[1].flags = I2C_M_RD;
+		msgr[1].len = 1;
+		msgr[1].buf = msg->buf;
+		size = 2;
+		rc = i2c_transfer(priv->i2c_adap, msgr, size);
+		msg->buf[msg->len - 1] = msgr[1].buf[0];
+	} else {
+		rc = i2c_transfer(priv->i2c_adap, msg, size);
+	}
 	if (fe->ops.i2c_gate_ctrl)
 		fe->ops.i2c_gate_ctrl(fe, 0);
 
diff -urN linux/drivers/media/common/tuners/tda827x.h linux.new/drivers/media/common/tuners/tda827x.h
--- linux/drivers/media/common/tuners/tda827x.h	2010-07-03 23:22:08.000000000 +0200
+++ linux.new/drivers/media/common/tuners/tda827x.h	2011-05-21 22:48:31.484340005 +0200
@@ -38,6 +38,8 @@ 
 	int 	     switch_addr;
 
 	void (*agcf)(struct dvb_frontend *fe);
+
+	u8 i2cr;
 };
 
 
diff -urN linux/drivers/media/dvb/dvb-usb/ttusb2.c linux.new/drivers/media/dvb/dvb-usb/ttusb2.c
--- linux/drivers/media/dvb/dvb-usb/ttusb2.c	2011-01-10 16:24:45.000000000 +0100
+++ linux.new/drivers/media/dvb/dvb-usb/ttusb2.c	2011-06-06 14:35:37.906154000 +0200
@@ -30,6 +30,7 @@ 
 #include "tda826x.h"
 #include "tda10086.h"
 #include "tda1002x.h"
+#include "tda10048.h"
 #include "tda827x.h"
 #include "lnbp21.h"
 
@@ -44,6 +45,8 @@ 
 struct ttusb2_state {
 	u8 id;
 	u16 last_rc_key;
+	struct dvb_frontend *fe;
+	u8 initialized;
 };
 
 static int ttusb2_msg(struct dvb_usb_device *d, u8 cmd,
@@ -155,7 +158,6 @@ 
 	return 0;
 }
 
-
 /* Callbacks for DVB USB */
 static int ttusb2_identify_state (struct usb_device *udev, struct
 		dvb_usb_device_properties *props, struct dvb_usb_device_description **desc,
@@ -167,11 +169,58 @@ 
 
 static int ttusb2_power_ctrl(struct dvb_usb_device *d, int onoff)
 {
+	struct ttusb2_state *state;
 	u8 b = onoff;
-	ttusb2_msg(d, CMD_POWER, &b, 0, NULL, 0);
-	return ttusb2_msg(d, CMD_POWER, &b, 1, NULL, 0);
+	if (onoff) {
+		state = (struct ttusb2_state *)d->priv;
+		if (!state->initialized) {
+			ttusb2_msg(d, CMD_POWER, &b, 0, NULL, 0);
+			ttusb2_msg(d, CMD_POWER, &b, 1, NULL, 0);
+			state->initialized = 1;
+		}
+	}
+	return 0;
+}
+
+//get access to tuner
+static int lock_tuner(struct tda10048_state *state)
+{
+	u8 buf[2] = { 0x0f, 0xc0 };
+	struct i2c_msg msg = {.addr=0x0c, .flags=0, .buf=buf, .len=2};
+
+	if(i2c_transfer(state->i2c, &msg, 1) != 1)
+	{
+		printk("tda10048: lock tuner fails\n");
+		return -EREMOTEIO;
+	}
+	return 0;
 }
 
+//release access from tuner
+static int unlock_tuner(struct tda10048_state *state)
+{
+	u8 buf[2] = { 0x0f, 0x40 };
+	struct i2c_msg msg_post={.addr=0x0c, .flags=0, .buf=buf, .len=2};
+
+	if(i2c_transfer(state->i2c, &msg_post, 1) != 1)
+	{
+		printk("tda10048: unlock tuner fails\n");
+		return -EREMOTEIO;
+	}
+	return 0;
+}
+
+static int tda10023_i2c_gate_ctrl(struct dvb_frontend* fe, int enable)
+{
+	struct tda10048_state *state = fe->demodulator_priv;
+
+	if (enable) {
+		lock_tuner(state);
+	} else {
+		unlock_tuner(state);
+	}
+	return 0;
+}
 
 static struct tda10086_config tda10086_config = {
 	.demod_address = 0x0e,
@@ -190,6 +239,23 @@ 
 	.deltaf = 0xa511,
 };
 
+static struct tda10048_config tda10048_config = {
+	.demod_address    = 0x10 >> 1,
+	.output_mode      = TDA10048_PARALLEL_OUTPUT,
+	.inversion        = TDA10048_INVERSION_ON,
+	.dtv6_if_freq_khz = TDA10048_IF_4000,
+	.dtv7_if_freq_khz = TDA10048_IF_4500,
+	.dtv8_if_freq_khz = TDA10048_IF_5000,
+	.clk_freq_khz     = TDA10048_CLK_16000,
+	.no_firmware      = 1,
+	.i2c_gate         = tda10023_i2c_gate_ctrl,
+};
+
+static struct tda827x_config tda827x_config = {
+	.i2cr = 1,
+	.config = 0,
+};
+
 static int ttusb2_frontend_tda10086_attach(struct dvb_usb_adapter *adap)
 {
 	if (usb_set_interface(adap->dev->udev,0,3) < 0)
@@ -205,18 +271,30 @@ 
 
 static int ttusb2_frontend_tda10023_attach(struct dvb_usb_adapter *adap)
 {
+	struct ttusb2_state *state;
 	if (usb_set_interface(adap->dev->udev, 0, 3) < 0)
 		err("set interface to alts=3 failed");
 	if ((adap->fe = dvb_attach(tda10023_attach, &tda10023_config, &adap->dev->i2c_adap, 0x48)) == NULL) {
 		deb_info("TDA10023 attach failed\n");
 		return -ENODEV;
 	}
+	adap->fe->id = 1;
+	state = (struct ttusb2_state *)adap->dev->priv;
+	if ((state->fe = dvb_attach(tda10048_attach, &tda10048_config, &adap->dev->i2c_adap)) == NULL) {
+		deb_info("TDA10048 attach failed\n");
+		return -ENODEV;
+	}
+	dvb_register_frontend(&adap->dvb_adap, state->fe);
+	if (dvb_attach(tda827x_attach, state->fe, 0x61, &adap->dev->i2c_adap, &tda827x_config) == NULL) {
+		printk(KERN_ERR "%s: No tda827x found!\n", __func__);
+		return -ENODEV;
+	}
 	return 0;
 }
 
 static int ttusb2_tuner_tda827x_attach(struct dvb_usb_adapter *adap)
 {
-	if (dvb_attach(tda827x_attach, adap->fe, 0x61, &adap->dev->i2c_adap, NULL) == NULL) {
+	if (dvb_attach(tda827x_attach, adap->fe, 0x61, &adap->dev->i2c_adap, &tda827x_config) == NULL) {
 		printk(KERN_ERR "%s: No tda827x found!\n", __func__);
 		return -ENODEV;
 	}
@@ -242,6 +320,19 @@ 
 static struct dvb_usb_device_properties ttusb2_properties_s2400;
 static struct dvb_usb_device_properties ttusb2_properties_ct3650;
 
+static void ttusb2_usb_disconnect (struct usb_interface *intf)
+{
+	struct dvb_usb_device *d = usb_get_intfdata (intf);
+	struct ttusb2_state * state;
+
+	state = (struct ttusb2_state *)d->priv;
+	if (state->fe) {
+		dvb_unregister_frontend(state->fe);
+		dvb_frontend_detach(state->fe);
+	}
+	dvb_usb_device_exit (intf);
+}
+
 static int ttusb2_probe(struct usb_interface *intf,
 		const struct usb_device_id *id)
 {
@@ -422,7 +513,7 @@ 
 static struct usb_driver ttusb2_driver = {
 	.name		= "dvb_usb_ttusb2",
 	.probe		= ttusb2_probe,
-	.disconnect = dvb_usb_device_exit,
+	.disconnect = ttusb2_usb_disconnect,
 	.id_table	= ttusb2_table,
 };
diff -urN linux/drivers/media/dvb/frontends/tda10048.c linux.new/drivers/media/dvb/frontends/tda10048.c
--- linux/drivers/media/dvb/frontends/tda10048.c	2010-10-25 01:34:58.000000000 +0200
+++ linux.new/drivers/media/dvb/frontends/tda10048.c	2011-06-04 13:04:47.759000004 +0200
@@ -136,26 +136,6 @@ 
 		printk(KERN_DEBUG "tda10048: " fmt, ## arg);\
 	} while (0)
 
-struct tda10048_state {
-
-	struct i2c_adapter *i2c;
-
-	/* We'll cache and update the attach config settings */
-	struct tda10048_config config;
-	struct dvb_frontend frontend;
-
-	int fwloaded;
-
-	u32 freq_if_hz;
-	u32 xtal_hz;
-	u32 pll_mfactor;
-	u32 pll_nfactor;
-	u32 pll_pfactor;
-	u32 sample_freq;
-
-	enum fe_bandwidth bandwidth;
-};
-
 static struct init_tab {
 	u8	reg;
 	u16	data;
@@ -214,6 +194,8 @@ 
 	{ TDA10048_CLK_16000, TDA10048_IF_3800,  10, 3, 0 },
 	{ TDA10048_CLK_16000, TDA10048_IF_4000,  10, 3, 0 },
 	{ TDA10048_CLK_16000, TDA10048_IF_4300,  10, 3, 0 },
+	{ TDA10048_CLK_16000, TDA10048_IF_4500,  10, 3, 0 },
+	{ TDA10048_CLK_16000, TDA10048_IF_5000,  10, 3, 0 },
 	{ TDA10048_CLK_16000, TDA10048_IF_36130, 10, 3, 0 },
 };
 
@@ -710,12 +692,16 @@ 
 	if (config->disable_gate_access)
 		return 0;
 
-	if (enable)
-		return tda10048_writereg(state, TDA10048_CONF_C4_1,
-			tda10048_readreg(state, TDA10048_CONF_C4_1) | 0x02);
-	else
-		return tda10048_writereg(state, TDA10048_CONF_C4_1,
-			tda10048_readreg(state, TDA10048_CONF_C4_1) & 0xfd);
+	if (config->i2c_gate) {
+		return config->i2c_gate(fe, enable);
+	} else {
+		if (enable)
+			return tda10048_writereg(state, TDA10048_CONF_C4_1,
+				tda10048_readreg(state, TDA10048_CONF_C4_1) | 0x02);
+		else
+			return tda10048_writereg(state, TDA10048_CONF_C4_1,
+				tda10048_readreg(state, TDA10048_CONF_C4_1) & 0xfd);
+	}
 }
 
 static int tda10048_output_mode(struct dvb_frontend *fe, int serial)
@@ -785,7 +771,7 @@ 
 	for (i = 0; i < ARRAY_SIZE(init_tab); i++)
 		tda10048_writereg(state, init_tab[i].reg, init_tab[i].data);
 
-	if (state->fwloaded == 0)
+	if ((state->fwloaded == 0) && (!config->no_firmware))
 		ret = tda10048_firmware_upload(fe);
 
 	/* Set either serial or parallel */
diff -urN linux/drivers/media/dvb/frontends/tda10048.h linux.new/drivers/media/dvb/frontends/tda10048.h
--- linux/drivers/media/dvb/frontends/tda10048.h	2010-07-03 23:22:08.000000000 +0200
+++ linux.new/drivers/media/dvb/frontends/tda10048.h	2011-06-04 13:04:39.721000004 +0200
@@ -51,6 +51,7 @@ 
 #define TDA10048_IF_4300  4300
 #define TDA10048_IF_4500  4500
 #define TDA10048_IF_4750  4750
+#define TDA10048_IF_5000  5000
 #define TDA10048_IF_36130 36130
 	u16 dtv6_if_freq_khz;
 	u16 dtv7_if_freq_khz;
@@ -62,6 +63,30 @@ 
 
 	/* Disable I2C gate access */
 	u8 disable_gate_access;
+
+	u8 no_firmware;
+
+	int (*i2c_gate) (struct dvb_frontend *fe, int enable);
+};
+
+struct tda10048_state {
+
+	struct i2c_adapter *i2c;
+
+	/* We'll cache and update the attach config settings */
+	struct tda10048_config config;
+	struct dvb_frontend frontend;
+
+	int fwloaded;
+
+	u32 freq_if_hz;
+	u32 xtal_hz;
+	u32 pll_mfactor;
+	u32 pll_nfactor;
+	u32 pll_pfactor;
+	u32 sample_freq;
+
+	enum fe_bandwidth bandwidth;
 };
 
 #if defined(CONFIG_DVB_TDA10048) || \