Fwd: Twinhan vp7045, fighting for a lost cause ?

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Hi,

The code to make it work already is in the DVB-T tree, somebody "just" needs to glue the TDA10046 frontend to the existing VP7045 backend code, Steward has started this work but I don´t know if he has progressed further than the attached diff.

The firmware needs to be extracted from the windows driver, I have the information needed for that, but hopefully we will be allowed to redistribute the firmware instead.

I think Chris has both the new and the old stick, so he would be a perfect tester.

That is about all I know.

/Henrik









diff -r 443f5b4e2365 linux/drivers/media/dvb/dvb-usb/Makefile
--- a/linux/drivers/media/dvb/dvb-usb/Makefile	Sun Sep  3 16:33:10 2006
+++ b/linux/drivers/media/dvb/dvb-usb/Makefile	Thu Sep  7 03:11:12 2006
@@ -1,7 +1,7 @@
 dvb-usb-objs = dvb-usb-firmware.o dvb-usb-init.o dvb-usb-urb.o dvb-usb-i2c.o dvb-usb-dvb.o dvb-usb-remote.o
 obj-$(CONFIG_DVB_USB) += dvb-usb.o
 
-dvb-usb-vp7045-objs = vp7045.o vp7045-fe.o
+dvb-usb-vp7045-objs = vp7045.o
 obj-$(CONFIG_DVB_USB_VP7045) += dvb-usb-vp7045.o
 
 dvb-usb-vp702x-objs = vp702x.o vp702x-fe.o
diff -r 443f5b4e2365 linux/drivers/media/dvb/dvb-usb/dvb-usb-firmware.c
--- a/linux/drivers/media/dvb/dvb-usb/dvb-usb-firmware.c	Sun Sep  3 16:33:10 2006
+++ b/linux/drivers/media/dvb/dvb-usb/dvb-usb-firmware.c	Thu Sep  7 03:11:12 2006
@@ -52,27 +52,30 @@
 		ret = usb_cypress_writemem(udev,hx.addr,hx.data,hx.len);
 
 		if (ret != hx.len) {
-			err("error while transferring firmware "
-				"(transferred size: %d, block size: %d)",
+			printk("error while transferring firmware "
+				"(transferred size: %d, block size: %d)\n",
 				ret,hx.len);
 			ret = -EINVAL;
 			break;
 		}
 	}
 	if (ret < 0) {
-		err("firmware download failed at %d with %d",pos,ret);
+		printk("firmware download failed at %d with %d\n",pos,ret);
 		return ret;
 	}
 
 	if (ret == 0) {
 		/* restart the CPU */
 		reset = 0;
+		printk("restarting cpu\n");
 		if (ret || usb_cypress_writemem(udev,cypress[type].cpu_cs_register,&reset,1) != 1) {
-			err("could not restart the USB controller CPU.");
+			printk("could not restart the USB controller CPU.\n");
 			ret = -EINVAL;
 		}
-	} else
+	} else {
+	  printk("returning eio\n");
 		ret = -EIO;
+	}
 
 	return ret;
 }
@@ -110,7 +113,7 @@
 			ret = -EINVAL;
 			break;
 	}
-
+	printk("done, releasing firmware\n");
 	release_firmware(fw);
 	return ret;
 }
diff -r 443f5b4e2365 linux/drivers/media/dvb/dvb-usb/dvb-usb-i2c.c
--- a/linux/drivers/media/dvb/dvb-usb/dvb-usb-i2c.c	Sun Sep  3 16:33:10 2006
+++ b/linux/drivers/media/dvb/dvb-usb/dvb-usb-i2c.c	Thu Sep  7 03:11:12 2006
@@ -12,10 +12,13 @@
 	int ret = 0;
 
 	if (!(d->props.caps & DVB_USB_IS_AN_I2C_ADAPTER))
+	{
+	  printk("no cap\n");
 		return 0;
+	}
 
 	if (d->props.i2c_algo == NULL) {
-		err("no i2c algorithm specified");
+		printk("no i2c algorithm specified\n");
 		return -EINVAL;
 	}
 
@@ -31,7 +34,7 @@
 	i2c_set_adapdata(&d->i2c_adap, d);
 
 	if ((ret = i2c_add_adapter(&d->i2c_adap)) < 0)
-		err("could not add i2c adapter");
+		printk("could not add i2c adapter\n");
 
 	d->state |= DVB_USB_STATE_I2C;
 
diff -r 443f5b4e2365 linux/drivers/media/dvb/dvb-usb/dvb-usb-init.c
--- a/linux/drivers/media/dvb/dvb-usb/dvb-usb-init.c	Sun Sep  3 16:33:10 2006
+++ b/linux/drivers/media/dvb/dvb-usb/dvb-usb-init.c	Thu Sep  7 03:11:12 2006
@@ -69,11 +69,16 @@
 	if (d->props.power_ctrl)
 		d->props.power_ctrl(d,1);
 
-	if ((ret = dvb_usb_urb_init(d)) ||
-		(ret = dvb_usb_dvb_init(d)) ||
-		(ret = dvb_usb_i2c_init(d)) ||
-		(ret = dvb_usb_fe_init(d))) {
+	ret = dvb_usb_urb_init(d);
+	err("init urb %d", ret);
+	ret |= dvb_usb_dvb_init(d);
+	err("init dvb %d", ret);
+	ret |= dvb_usb_i2c_init(d);
+	err("init i2c %d", ret);
+	ret |= dvb_usb_fe_init(d);
+	if(ret) {
 		dvb_usb_exit(d);
+		err("failed initing. urb, dvb, i2c, fe %d", ret);
 		return ret;
 	}
 
diff -r 443f5b4e2365 linux/drivers/media/dvb/dvb-usb/dvb-usb.h
--- a/linux/drivers/media/dvb/dvb-usb/dvb-usb.h	Sun Sep  3 16:33:10 2006
+++ b/linux/drivers/media/dvb/dvb-usb/dvb-usb.h	Thu Sep  7 03:11:12 2006
@@ -327,6 +327,9 @@
 	struct module *owner;
 
 	void *priv;
+
+  u8 last_result[32]; // hack
+	u8 c;			/* transaction counter, wraps around...  */
 };
 
 extern int dvb_usb_device_init(struct usb_interface *, struct dvb_usb_properties *, struct module *, struct dvb_usb_device **);
diff -r 443f5b4e2365 linux/drivers/media/dvb/dvb-usb/vp7045.c
--- a/linux/drivers/media/dvb/dvb-usb/vp7045.c	Sun Sep  3 16:33:10 2006
+++ b/linux/drivers/media/dvb/dvb-usb/vp7045.c	Thu Sep  7 03:11:12 2006
@@ -13,6 +13,7 @@
  * see Documentation/dvb/README.dvb-usb for more information
  */
 #include "vp7045.h"
+#include "tda1004x.h"
 
 /* debug */
 int dvb_usb_vp7045_debug;
@@ -168,6 +169,22 @@
 {
 	return vp7045_read_eeprom(d,mac, 6, MAC_0_ADDR);
 }
+/*
+static int philips_tdm1316l_request_firmware(struct dvb_frontend* fe, const struct firmware **fw, char* name)
+{
+	struct ttusb* ttusb = (struct ttusb*) fe->dvb->priv;
+
+	return request_firmware(fw, name, &ttusb->dev->dev);
+}*/
+
+static struct tda1004x_config philips_tdm1316l_config = {
+
+	.demod_address = 0x31,
+	.invert = 1,
+	.invert_oclk = 0,
+	.request_firmware = NULL, //philips_tdm1316l_request_firmware,
+};
+
 
 static int vp7045_frontend_attach(struct dvb_usb_device *d)
 {
@@ -175,21 +192,38 @@
 
 	vp7045_usb_op(d,VENDOR_STRING_READ,NULL,0,buf,20,0);
 	buf[10] = '\0';
-	deb_info("firmware says: %s ",buf);
+	printk("firmware says: %s\n",buf);
 
 	vp7045_usb_op(d,PRODUCT_STRING_READ,NULL,0,buf,20,0);
 	buf[10] = '\0';
-	deb_info("%s ",buf);
+	printk("%s\n",buf);
 
 	vp7045_usb_op(d,FW_VERSION_READ,NULL,0,buf,20,0);
 	buf[10] = '\0';
-	deb_info("v%s\n",buf);
-
+	printk("v%s\n",buf);
+
+/*	u8 obuf[3] = { 0x00, 0x7f,0x01 },tuner;
+
+vp7045_usb_op(d,TUNER_REG_READ,obuf,3,&tuner,1,30);*/
+	u32 tuner = vp7045_read_reg(d,0x7F);
+	switch(tuner)
+	{
+	case 0x14:
+	  printk("VP7045 Tuner is MT353\n");
+	  break;
+	case 0x13:
+	  printk("VP7045 Tuner is MT352\n");
+	default:
+	  printk("UNKNOWN TUNER 0x%x!!!!\n",tuner);
+	}
 /*	Dump the EEPROM */
 /*	vp7045_read_eeprom(d,buf, 255, FX2_ID_ADDR); */
 
-	d->fe = vp7045_fe_attach(d);
-
+//	d->fe = vp7045_fe_attach(d);
+
+	printk("The i2c_adap: %p\n", d->i2c_adap);
+	d->fe = tda10046_attach(&philips_tdm1316l_config, &d->i2c_adap);
+		//	d->fe = tda10046_attach();
 	return 0;
 }
 
@@ -210,8 +244,174 @@
 };
 MODULE_DEVICE_TABLE(usb, vp7045_usb_table);
 
+#define DEBUG 0
+static int ttusb_cmd(struct dvb_usb_device *d,
+	      const u8 * data, int len, int needresult)
+{
+	int actual_len;
+	int err;
+#if DEBUG >= 3
+	int i;
+
+	printk(">");
+	for (i = 0; i < len; ++i)
+		printk(" %02x", data[i]);
+	printk("\n");
+#endif
+
+	if (mutex_lock_interruptible(&d->usb_mutex) < 0)
+		return -EAGAIN;
+
+	err = usb_bulk_msg(d->udev, usb_sndbulkpipe(d->udev,
+			d->props.generic_bulk_ctrl_endpoint),
+			   (u8 *) data, len, &actual_len, 1000);
+	if (err != 0) {
+		printk("%s: usb_bulk_msg(send) failed, err == %i!\n",
+			__FUNCTION__, err);
+		mutex_unlock(&d->usb_mutex);
+		return err;
+	}
+	if (actual_len != len) {
+		printk("%s: only wrote %d of %d bytes\n", __FUNCTION__,
+			actual_len, len);
+		mutex_unlock(&d->usb_mutex);
+		return -1;
+	}
+
+	err = usb_bulk_msg(d->udev, usb_sndbulkpipe(d->udev,
+			d->props.generic_bulk_ctrl_endpoint),
+			   d->last_result, 32, &actual_len, 1000);
+
+	if (err != 0) {
+		printk("%s: failed, receive error %d\n", __FUNCTION__,
+		       err);
+		mutex_unlock(&d->usb_mutex);
+		return err;
+	}
+#if DEBUG >= 3
+	actual_len = d->last_result[3] + 4;
+	printk("<");
+	for (i = 0; i < actual_len; ++i)
+		printk(" %02x", d->last_result[i]);
+	printk("\n");
+#endif
+	if (!needresult)
+		mutex_unlock(&d->usb_mutex);
+	return 0;
+}
+
+static int ttusb_result(struct dvb_usb_device *d, u8 * data, int len)
+{
+	memcpy(data, d->last_result, len);
+	mutex_unlock(&d->usb_mutex);
+	return 0;
+}
+
+static int ttusb_i2c_msg(struct dvb_usb_device *d,
+		  u8 addr, u8 * snd_buf, u8 snd_len, u8 * rcv_buf,
+		  u8 rcv_len)
+{
+	u8 b[0x28];
+	u8 id = ++d->c;
+	int i, err;
+
+	if (snd_len > 0x28 - 7 || rcv_len > 0x20 - 7)
+		return -EINVAL;
+
+	b[0] = 0xaa;
+	b[1] = id;
+	b[2] = 0x31;
+	b[3] = snd_len + 3;
+	b[4] = addr << 1;
+	b[5] = snd_len;
+	b[6] = rcv_len;
+
+	for (i = 0; i < snd_len; i++)
+		b[7 + i] = snd_buf[i];
+
+	err = ttusb_cmd(d, b, snd_len + 7, 1);
+
+	if (err)
+		return -EREMOTEIO;
+
+	err = ttusb_result(d, b, 0x20);
+
+	/* check if the i2c transaction was successful */
+	if ((snd_len != b[5]) || (rcv_len != b[6])) return -EREMOTEIO;
+
+	if (rcv_len > 0) {
+
+		if (err || b[0] != 0x55 || b[1] != id) {
+			printk
+			    ("%s: usb_bulk_msg(recv) failed, err == %i, id == %02x, b == ",
+			     __FUNCTION__, err, id);
+			return -EREMOTEIO;
+		}
+
+		for (i = 0; i < rcv_len; i++)
+			rcv_buf[i] = b[7 + i];
+	}
+
+	return rcv_len;
+}
+
+static int master_xfer(struct i2c_adapter* adapter, struct i2c_msg *msg, int num)
+{
+	struct dvb_usb_device *d = i2c_get_adapdata(adapter);
+	int i = 0;
+	int inc;
+
+	if (mutex_lock_interruptible(&d->i2c_mutex) < 0)
+		return -EAGAIN;
+
+	while (i < num) {
+		u8 addr, snd_len, rcv_len, *snd_buf, *rcv_buf;
+		int err;
+
+		if (num > i + 1 && (msg[i + 1].flags & I2C_M_RD)) {
+			addr = msg[i].addr;
+			snd_buf = msg[i].buf;
+			snd_len = msg[i].len;
+			rcv_buf = msg[i + 1].buf;
+			rcv_len = msg[i + 1].len;
+			inc = 2;
+		} else {
+			addr = msg[i].addr;
+			snd_buf = msg[i].buf;
+			snd_len = msg[i].len;
+			rcv_buf = NULL;
+			rcv_len = 0;
+			inc = 1;
+		}
+
+		err = ttusb_i2c_msg(d, addr,
+				    snd_buf, snd_len, rcv_buf, rcv_len);
+
+		if (err < rcv_len) {
+			printk("%s: i == %i\n", __FUNCTION__, i);
+			break;
+		}
+
+		i += inc;
+	}
+
+	mutex_unlock(&d->i2c_mutex);
+	return i;
+}
+
+static u32 functionality(struct i2c_adapter *adapter)
+{
+	return I2C_FUNC_I2C;
+}
+
+static struct i2c_algorithm ttusb_dec_algo = {
+	.master_xfer	= master_xfer,
+	.functionality	= functionality,
+};
+
+
 static struct dvb_usb_properties vp7045_properties = {
-	.caps = 0,
+	.caps = DVB_USB_IS_AN_I2C_ADAPTER,
 
 	.usb_ctrl = CYPRESS_FX2,
 	.firmware = "dvb-usb-vp7045-01.fw",
@@ -220,6 +420,9 @@
 	.frontend_attach  = vp7045_frontend_attach,
 	.read_mac_address = vp7045_read_mac_addr,
 
+	.i2c_algo         = &ttusb_dec_algo, 
+
+	.no_reconnect = 1,
 	.rc_interval      = 400,
 	.rc_key_map       = vp7045_rc_keys,
 	.rc_key_map_size  = ARRAY_SIZE(vp7045_rc_keys),

Attachment: dvb-usb-vp7045-01.fw
Description: Binary data

_______________________________________________
linux-dvb mailing list
linux-dvb@xxxxxxxxxxx
http://www.linuxtv.org/cgi-bin/mailman/listinfo/linux-dvb

[Index of Archives]     [Linux Media]     [Video 4 Linux]     [Asterisk]     [Samba]     [Xorg]     [Xfree86]     [Linux USB]

  Powered by Linux