summaryrefslogtreecommitdiff
path: root/linux
diff options
context:
space:
mode:
authorMichael Hunold <devnull@localhost>2003-12-21 15:18:44 +0000
committerMichael Hunold <devnull@localhost>2003-12-21 15:18:44 +0000
commit56325ebe82f12b17a36ee96f5c0f4604dbd9dbe6 (patch)
tree594d7de4f48086a43cb34e159b1422d2de551256 /linux
parent28eae47f376c13563c02c2c3a368b20951c45009 (diff)
downloadmediapointer-dvb-s2-56325ebe82f12b17a36ee96f5c0f4604dbd9dbe6.tar.gz
mediapointer-dvb-s2-56325ebe82f12b17a36ee96f5c0f4604dbd9dbe6.tar.bz2
- apply dvb-ttpci/av7110 firmware removal from 2.6.0 patch here, too, but:
the firmware is still compiled into the driver for 2.4 by default, the necessary files are created dynamically from the firmware file. get it from http://www.linuxtv.org/download/dvb/dvb-ttpci-01.fw - revamp fdump utility to be smarter when the source file isn't there
Diffstat (limited to 'linux')
-rw-r--r--linux/drivers/media/dvb/ttpci/av7110.c121
-rw-r--r--linux/drivers/media/dvb/ttpci/av7110.h14
-rw-r--r--linux/drivers/media/dvb/ttusb-dec/fdump.c64
3 files changed, 157 insertions, 42 deletions
diff --git a/linux/drivers/media/dvb/ttpci/av7110.c b/linux/drivers/media/dvb/ttpci/av7110.c
index 2b30ba183..480752351 100644
--- a/linux/drivers/media/dvb/ttpci/av7110.c
+++ b/linux/drivers/media/dvb/ttpci/av7110.c
@@ -60,6 +60,8 @@
#include <linux/inetdevice.h>
#include <linux/etherdevice.h>
#include <linux/skbuff.h>
+#include <linux/firmware.h>
+#include <linux/crc32.h>
#include <asm/system.h>
#include <asm/bitops.h>
@@ -1971,8 +1973,6 @@ static u8 bootcode[] = {
0x2c, 0x00, 0x03, 0xf8, 0x2c, 0x00, 0x04, 0x00,
};
-#include "av7110_firm.h"
-
static int bootarm(struct av7110 *av7110)
{
struct saa7146_dev *dev= av7110->dev;
@@ -2025,7 +2025,7 @@ static int bootarm(struct av7110 *av7110)
DEB_D(("bootarm: load dram code\n"));
- if (load_dram(av7110, (u32 *)Root, sizeof(Root))<0)
+ if (load_dram(av7110, (u32 *)av7110->bin_root, av7110->size_root)<0)
return -1;
saa7146_setgpio(dev, RESET_LINE, SAA7146_GPIO_OUTLO);
@@ -2033,7 +2033,7 @@ static int bootarm(struct av7110 *av7110)
DEB_D(("bootarm: load dpram code\n"));
- mwdebi(av7110, DEBISWAB, DPRAM_BASE, Dpram, sizeof(Dpram));
+ mwdebi(av7110, DEBISWAB, DPRAM_BASE, av7110->bin_dpram, av7110->size_dpram);
wait_for_debi_done(av7110);
@@ -4500,24 +4500,110 @@ static u8 saa7113_init_regs[] = {
static struct saa7146_ext_vv av7110_vv_data_st;
static struct saa7146_ext_vv av7110_vv_data_c;
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0))
+#include "av7110_firm.h"
+#endif
+
static int av7110_attach (struct saa7146_dev* dev, struct saa7146_pci_extension_data *pci_ext)
{
+ struct firmware *fw;
struct av7110 *av7110 = NULL;
int ret = 0;
-
+ u32 crc = 0, len = 0;
+ unsigned char *ptr;
+
+ DEB_EE(("dev: %p, av7110: %p\n",dev,av7110));
+
+#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,0))
+ /* request the av7110 firmware, this will block until someone uploads it */
+ ret = request_firmware(&fw, "dvb-ttpci-01.fw", &dev->pci->dev);
+ if ( 0 != ret ) {
+ printk("dvb-ttpci: cannot request firmware!\n");
+ return -EINVAL;
+ }
+#else
+ fw = vmalloc(sizeof(struct firmware));
+ if (NULL == fw) {
+ printk("dvb-ttpci: not enough memory\n");
+ return -ENOMEM;
+ }
+ fw->size = sizeof(dvb_ttpci_fw);
+ fw->data = dvb_ttpci_fw;
+#endif
+
+ if (fw->size <= 200000) {
+ printk("dvb-ttpci: this firmware is way too small.\n");
+ return -EINVAL;
+ }
+
+ /* prepare the av7110 device struct */
if (!(av7110 = kmalloc (sizeof (struct av7110), GFP_KERNEL))) {
printk ("%s: out of memory!\n", __FUNCTION__);
return -ENOMEM;
}
-
memset(av7110, 0, sizeof(struct av7110));
+
+ /* check if the firmware is available */
+ av7110->bin_fw = (unsigned char*)vmalloc(fw->size);
+ if (NULL == av7110->bin_fw) {
+ DEB_D(("out of memory\n"));
+ kfree(av7110);
+ return -ENOMEM;
+ }
+ memcpy(av7110->bin_fw, fw->data, fw->size);
+ av7110->size_fw = fw->size;
+
+ /* check for firmware magic */
+ ptr = av7110->bin_fw;
+ if (ptr[0] != 'A' || ptr[1] != 'V' ||
+ ptr[2] != 'F' || ptr[3] != 'W') {
+ printk("dvb-ttpci: this is not an av7110 firmware\n");
+ goto fw_error;
+ }
+ ptr += 4;
+
+ /* check dpram file */
+ crc = ntohl(*(u32*)ptr);
+ ptr += 4;
+ len = ntohl(*(u32*)ptr);
+ ptr += 4;
+ if (len >= 512) {
+ printk("dvb-ttpci: dpram file is way to big.\n");
+ goto fw_error;
+ }
+ if( crc != crc32_le(0,ptr,len)) {
+ printk("dvb-ttpci: crc32 of dpram file does not match.\n");
+ goto fw_error;
+ }
+ av7110->bin_dpram = ptr;
+ av7110->size_dpram = len;
+ ptr += len;
+
+ /* check root file */
+ crc = ntohl(*(u32*)ptr);
+ ptr += 4;
+ len = ntohl(*(u32*)ptr);
+ ptr += 4;
+
+ if (len <= 200000 || len >= 300000 || len > ((av7110->bin_fw+av7110->size_fw)-ptr) ) {
+ printk("dvb-ttpci: root file has strange size (%d). aborting.\n",len);
+ goto fw_error;
+ }
+ if( crc != crc32_le(0,ptr,len)) {
+ printk("dvb-ttpci: crc32 of dpram file does not match.\n");
+ goto fw_error;
+ }
+ av7110->bin_root = ptr;
+ av7110->size_root = len;
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0))
+ vfree(fw);
+#endif
+ /* go on with regular device initialization */
av7110->card_name = (char*)pci_ext->ext_priv;
+ av7110->dev=(struct saa7146_dev *)dev;
(struct av7110*)dev->ext_priv = av7110;
- DEB_EE(("dev: %p, av7110: %p\n",dev,av7110));
-
- av7110->dev=(struct saa7146_dev *)dev;
dvb_register_adapter(&av7110->dvb_adapter, av7110->card_name);
/* the Siemens DVB needs this if you want to have the i2c chips
@@ -4758,6 +4844,7 @@ static int av7110_attach (struct saa7146_dev* dev, struct saa7146_pci_extension_
}
printk(KERN_INFO "av7110: found av7110-%d.\n",av7110_num);
+ av7110->device_initialized = 1;
av7110_num++;
return 0;
@@ -4781,12 +4868,20 @@ err:
dvb_unregister_adapter (av7110->dvb_adapter);
return ret;
+fw_error:
+ vfree(av7110->bin_fw);
+ kfree(av7110);
+ return -EINVAL;
}
static int av7110_detach (struct saa7146_dev* saa)
{
struct av7110 *av7110 = (struct av7110*)saa->ext_priv;
DEB_EE(("av7110: %p\n",av7110));
+
+ if( 0 == av7110->device_initialized ) {
+ return 0;
+ }
saa7146_unregister_device(&av7110->v4l_dev, saa);
if (2 == av7110->has_analog_tuner) {
@@ -4817,11 +4912,13 @@ static int av7110_detach (struct saa7146_dev* saa)
dvb_unregister_i2c_bus (master_xfer,av7110->i2c_bus->adapter, av7110->i2c_bus->id);
dvb_unregister_adapter (av7110->dvb_adapter);
+ av7110_num--;
+ if (NULL != av7110->bin_fw ) {
+ vfree(av7110->bin_fw);
+ }
kfree (av7110);
-
saa->ext_priv = NULL;
- av7110_num--;
-
+
return 0;
}
diff --git a/linux/drivers/media/dvb/ttpci/av7110.h b/linux/drivers/media/dvb/ttpci/av7110.h
index da8a9ad32..3c76b0325 100644
--- a/linux/drivers/media/dvb/ttpci/av7110.h
+++ b/linux/drivers/media/dvb/ttpci/av7110.h
@@ -1,8 +1,6 @@
#ifndef _AV7110_H_
#define _AV7110_H_
-#define DVB_FIRM_PATH "/lib/DVB/"
-
#include <linux/interrupt.h>
#include <linux/socket.h>
#include <linux/netdevice.h>
@@ -545,6 +543,18 @@ struct av7110 {
int dsp_dev;
u32 ir_config;
+
+ /* firmware stuff */
+ unsigned int device_initialized;
+
+ unsigned char *bin_fw;
+ unsigned long size_fw;
+
+ unsigned char *bin_dpram;
+ unsigned long size_dpram;
+
+ unsigned char *bin_root;
+ unsigned long size_root;
};
diff --git a/linux/drivers/media/dvb/ttusb-dec/fdump.c b/linux/drivers/media/dvb/ttusb-dec/fdump.c
index 834314a45..0b478db3e 100644
--- a/linux/drivers/media/dvb/ttusb-dec/fdump.c
+++ b/linux/drivers/media/dvb/ttusb-dec/fdump.c
@@ -4,33 +4,41 @@
#include <fcntl.h>
#include <unistd.h>
-
-int main (int argc, char **argv)
+int main(int argc, char **argv)
{
- unsigned char buf[8];
- unsigned int i, count, bytes = 0;
- int fd;
-
- if (argc != 3) {
- fprintf (stderr, "\n\tusage: %s <ucode.bin> <array_name>\n\n",
- argv[0]);
- return -1;
- }
-
- fd = open (argv[1], O_RDONLY);
-
- printf ("\n#include <asm/types.h>\n\nu8 %s [] __initdata = {",
- argv[2]);
-
- while ((count = read (fd, buf, 8)) > 0) {
- printf ("\n\t");
- for (i=0;i<count;i++, bytes++)
- printf ("0x%02x, ", buf[i]);
- }
-
- printf ("\n};\n\n");
- close (fd);
-
- return 0;
+ unsigned char buf[8];
+ unsigned int i, count, bytes = 0;
+ FILE *fd_in, *fd_out;
+
+ if (argc != 4) {
+ fprintf(stderr, "\n\tusage: %s <ucode.bin> <array_name> <output_name>\n\n", argv[0]);
+ return -1;
+ }
+
+ fd_in = fopen(argv[1], "rb");
+ if (fd_in == NULL) {
+ fprintf(stderr, "firmware file '%s' not found\n", argv[1]);
+ return -1;
+ }
+
+ fd_out = fopen(argv[3], "w+");
+ if (fd_out == NULL) {
+ fprintf(stderr, "cannot create output file '%s'\n", argv[3]);
+ return -1;
+ }
+
+ fprintf(fd_out, "\n#include <asm/types.h>\n\nu8 %s [] = {", argv[2]);
+
+ while ((count = fread(buf, 1, 8, fd_in)) > 0) {
+ fprintf(fd_out, "\n\t");
+ for (i = 0; i < count; i++, bytes++)
+ fprintf(fd_out, "0x%02x, ", buf[i]);
+ }
+
+ fprintf(fd_out, "\n};\n\n");
+
+ fclose(fd_in);
+ fclose(fd_out);
+
+ return 0;
}
-