Mailing List archive

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

[linux-dvb] Re: Reception performance with Avermedia DVB-T



Holger,

On Tuesday 18 November 2003 23:23, Holger Waechtler wrote:
> Hi Martin,
>
>
> Your patch did not applied for me, there have been too many conflicts.
> Can you please generate it using
>
> $ cvs -q diff -pu
>
> again? btw: your code looks good but the Kconfig file should contain the
> comment how to extract the firmware, too. The TDA10046 entry is a good
> example.
>
> Many thanks,
>
> Holger
>

Attached is the new patch, created as you suggest.

Martin
Index: linux/drivers/media/dvb/frontends/Kconfig
===================================================================
RCS file: /cvs/linuxtv/dvb-kernel/linux/drivers/media/dvb/frontends/Kconfig,v
retrieving revision 1.14
diff -u -3 -p -p -u -r1.14 Kconfig
--- linux/drivers/media/dvb/frontends/Kconfig	13 Oct 2003 04:11:27 -0000	1.14
+++ linux/drivers/media/dvb/frontends/Kconfig	19 Nov 2003 12:42:56 -0000
@@ -155,3 +155,19 @@ config DVB_TDA1004X_FIRMWARE_FILE
             wget http://www.technotrend.de/new/215/TTweb_215a_budget_20_05_2003.zip
             unzip -j TTweb_215a_budget_20_05_2003.zip Software/Oem/PCI/App/ttlcdacc.dll
             mv ttlcdacc.dll /etc/dvb/tda1004x.bin
+
+config DVB_SP887X_FIRMWARE_FILE
+        string "Full pathname of sp887x firmware file"
+        depends on DVB_SP887X
+        default "/etc/dvb/sc_main.mc"
+        help
+          This driver needs a copy of the Avermedia firmware. The version tested
+	  is part of the Avermedia DVB-T 1.3.26.3 Application. This can be downloaded
+	  from the Avermedia web site.
+	  If the software is installed in Windows the file will be in the
+	  /Program Files/AVerTV DVB-T/ directory and is called sc_main.mc.
+	  Alternatively it can "extracted" from the install cab files but this will have
+	  to be done in windows as I don't know of a linux version of extract.exe.
+	  Copy this file to /etc/dvb/sc_main.mc. With this version of the file the first
+	  10 bytes are discarded and the next 0x4000 loaded. This may change in future
+	  versions.
\ No newline at end of file
Index: linux/drivers/media/dvb/frontends/sp887x.c
===================================================================
RCS file: /cvs/linuxtv/dvb-kernel/linux/drivers/media/dvb/frontends/sp887x.c,v
retrieving revision 1.5
diff -u -3 -p -p -u -r1.5 sp887x.c
--- linux/drivers/media/dvb/frontends/sp887x.c	11 Nov 2003 12:30:36 -0000	1.5
+++ linux/drivers/media/dvb/frontends/sp887x.c	19 Nov 2003 12:42:56 -0000
@@ -1,11 +1,39 @@
+/*
+   Driver for the Microtune 7202D Frontend
+*/
+
+/*
+   This driver needs a copy of the Avermedia firmware. The version tested
+   is part of the Avermedia DVB-T 1.3.26.3 Application. If the software is
+   installed in Windows the file will be in the /Program Files/AVerTV DVB-T/
+   directory and is called sc_main.mc. Alternatively it can "extracted" from
+   the install cab files. Copy this file to /etc/dvb/sc_main.mc.
+   With this version of the file the first 10 bytes are discarded and the
+   next 0x4000 loaded. This may change in future versions.
+ */
 
+#define __KERNEL_SYSCALLS__
+#include <linux/kernel.h>
+#include <linux/vmalloc.h>
 #include <linux/module.h>
 #include <linux/init.h>
+#include <linux/string.h>
+#include <linux/slab.h>
+#include <linux/fs.h>
+#include <linux/unistd.h>
+#include <linux/fcntl.h>
+#include <linux/errno.h>
 #include <linux/i2c.h>
 
+
 #include "dvb_frontend.h"
 #include "dvb_functions.h"
 
+#ifndef DVB_SP887X_FIRMWARE_FILE
+#define DVB_SP887X_FIRMWARE_FILE "/etc/dvb/sc_main.mc"
+#endif
+
+static char *sp887x_firmware = DVB_SP887X_FIRMWARE_FILE;
 
 #if 0
 #define dprintk(x...) printk(x)
@@ -39,7 +67,7 @@ struct dvb_frontend_info sp887x_info = {
 		FE_CAN_QPSK | FE_CAN_QAM_16 | FE_CAN_QAM_64 | FE_CAN_RECOVER
 };
 
-
+static int errno;
 
 static
 int i2c_writebytes (struct dvb_frontend *fe, u8 addr, u8 *buf, u8 len)
@@ -75,7 +103,7 @@ int sp887x_writereg (struct dvb_frontend
 		/**
 		 *  in case of soft reset we ignore ACK errors...
 		 */
-		if (!(reg == 0xf1a && data == 0x000 && 
+		if (!(reg == 0xf1a && data == 0x000 &&
 			(ret == -EREMOTEIO || ret == -EFAULT)))
 		{
 			printk("%s: writereg error "
@@ -112,8 +140,9 @@ u16 sp887x_readreg (struct dvb_frontend 
 static
 void sp887x_microcontroller_stop (struct dvb_frontend *fe)
 {
+	dprintk("%s\n", __FUNCTION__);
 	sp887x_writereg(fe, 0xf08, 0x000);
-	sp887x_writereg(fe, 0xf09, 0x000);		
+	sp887x_writereg(fe, 0xf09, 0x000);
 
 	/* microcontroller STOP */
 	sp887x_writereg(fe, 0xf00, 0x000);
@@ -123,8 +152,9 @@ void sp887x_microcontroller_stop (struct
 static
 void sp887x_microcontroller_start (struct dvb_frontend *fe)
 {
+	dprintk("%s\n", __FUNCTION__);
 	sp887x_writereg(fe, 0xf08, 0x000);
-	sp887x_writereg(fe, 0xf09, 0x000);		
+	sp887x_writereg(fe, 0xf09, 0x000);
 
 	/* microcontroller START */
 	sp887x_writereg(fe, 0xf00, 0x001);
@@ -135,6 +165,7 @@ static
 void sp887x_setup_agc (struct dvb_frontend *fe)
 {
 	/* setup AGC parameters */
+	dprintk("%s\n", __FUNCTION__);
 	sp887x_writereg(fe, 0x33c, 0x054);
 	sp887x_writereg(fe, 0x33b, 0x04c);
 	sp887x_writereg(fe, 0x328, 0x000);
@@ -152,8 +183,6 @@ void sp887x_setup_agc (struct dvb_fronte
 }
 
 
-#include "sp887x_firm.h"
-
 #define BLOCKSIZE 30
 
 /**
@@ -163,13 +192,61 @@ static
 int sp887x_initial_setup (struct dvb_frontend *fe)
 {
 	u8 buf [BLOCKSIZE+2];
+	unsigned char *firmware = NULL;
 	int i;
+	int fd;
+	int filesize;
+	int fw_size;
+
+	dprintk("%s\n", __FUNCTION__);
 
 	/* soft reset */
 	sp887x_writereg(fe, 0xf1a, 0x000);
 
 	sp887x_microcontroller_stop (fe);
 
+	mm_segment_t fs = get_fs();
+
+	// Load the firmware
+	set_fs(get_ds());
+	fd = open(sp887x_firmware, 0, 0);
+	if (fd < 0) {
+		printk(KERN_WARNING "%s: Unable to open firmware %s\n", __FUNCTION__,
+		       sp887x_firmware);
+		return -EIO;
+	}
+	filesize = lseek(fd, 0L, 2);
+	if (filesize <= 0) {
+		printk(KERN_WARNING "%s: Firmware %s is empty\n", __FUNCTION__,
+		       sp887x_firmware);
+		sys_close(fd);
+		return -EIO;
+	}
+
+	fw_size = 0x4000;
+
+	// allocate buffer for it
+	firmware = vmalloc(fw_size);
+	if (firmware == NULL) {
+		printk(KERN_WARNING "%s: Out of memory loading firmware\n",
+		       __FUNCTION__);
+		sys_close(fd);
+		return -EIO;
+	}
+
+	// read it!
+	// read the first 16384 bytes from the file
+	// ignore the first 10 bytes
+	lseek(fd, 10, 0);
+	if (read(fd, firmware, fw_size) != fw_size) {
+		printk(KERN_WARNING "%s: Failed to read firmware\n", __FUNCTION__);
+		vfree(firmware);
+		sys_close(fd);
+		return -EIO;
+	}
+	sys_close(fd);
+	set_fs(fs);
+
 	printk ("%s: firmware upload... ", __FUNCTION__);
 
 	/* setup write pointer to -1 (end of memory) */
@@ -179,12 +256,12 @@ int sp887x_initial_setup (struct dvb_fro
 	/* dummy write (wrap around to start of memory) */
 	sp887x_writereg(fe, 0x8f0a, 0x0000);
 
-	for (i=0; i<sizeof(sp887x_firm); i+=BLOCKSIZE) {
+	for (i=0; i<fw_size; i+=BLOCKSIZE) {
 		int c = BLOCKSIZE;
 		int err;
 
-		if (i+c > sizeof(sp887x_firm))
-			c = sizeof(sp887x_firm) - i;
+		if (i+c > fw_size)
+			c = fw_size - i;
 
 		/* bit 0x8000 in address is set to enable 13bit mode */
 		/* bit 0x4000 enables multibyte read/write transfers */
@@ -192,14 +269,17 @@ int sp887x_initial_setup (struct dvb_fro
 		buf[0] = 0xcf;
 		buf[1] = 0x0a;
 
-		memcpy(&buf[2], &sp887x_firm[i], c);
+		memcpy(&buf[2], firmware + i, c);
 
 		if ((err = i2c_writebytes (fe, 0x70, buf, c+2)) < 0) {
 			printk ("failed.\n");
 			printk ("%s: i2c error (err == %i)\n", __FUNCTION__, err);
+			vfree(firmware);
 			return err;
 		}
 	}
+
+	vfree(firmware);
 
 	/* don't write RS bytes between packets */
 	sp887x_writereg(fe, 0xc13, 0x001);

Home | Main Index | Thread Index