summaryrefslogtreecommitdiff
path: root/linux/drivers/media/dvb/ttusb-dec/ttusb_dec.c
diff options
context:
space:
mode:
Diffstat (limited to 'linux/drivers/media/dvb/ttusb-dec/ttusb_dec.c')
-rw-r--r--linux/drivers/media/dvb/ttusb-dec/ttusb_dec.c58
1 files changed, 49 insertions, 9 deletions
diff --git a/linux/drivers/media/dvb/ttusb-dec/ttusb_dec.c b/linux/drivers/media/dvb/ttusb-dec/ttusb_dec.c
index 66fe0e6d5..4341591bc 100644
--- a/linux/drivers/media/dvb/ttusb-dec/ttusb_dec.c
+++ b/linux/drivers/media/dvb/ttusb-dec/ttusb_dec.c
@@ -28,6 +28,9 @@
#include <linux/usb.h>
#include <linux/version.h>
#include <linux/interrupt.h>
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)
+#include <linux/firmware.h>
+#endif
#include "dmxdev.h"
#include "dvb_demux.h"
@@ -66,6 +69,7 @@ enum ttusb_model {
struct ttusb_dec {
enum ttusb_model model;
char *model_name;
+ char *firmware_name;
/* DVB bits */
struct dvb_adapter *adapter;
@@ -110,6 +114,8 @@ struct ttusb_dec {
struct list_head urb_frame_list;
struct tasklet_struct urb_tasklet;
spinlock_t urb_frame_list_lock;
+
+ int active; /* Loaded successfully */
};
struct urb_frame {
@@ -821,8 +827,10 @@ static void ttusb_dec_init_usb(struct ttusb_dec *dec)
ttusb_dec_alloc_iso_urbs(dec);
}
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
#include "dsp_dec2000t.h"
#include "dsp_dec3000s.h"
+#endif
static int ttusb_dec_boot_dsp(struct ttusb_dec *dec)
{
@@ -836,19 +844,36 @@ static int ttusb_dec_boot_dsp(struct ttusb_dec *dec)
u32 firmware_csum = 0;
u32 firmware_size_nl;
u32 firmware_csum_nl;
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)
+ const struct firmware *fw_entry = NULL;
+#endif
dprintk("%s\n", __FUNCTION__);
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)
+ if (request_firmware(&fw_entry, dec->firmware_name, &dec->udev->dev)) {
+ printk(KERN_ERR "%s: Firmware (%s) unavailable.\n",
+ __FUNCTION__, dec->firmware_name);
+ return 1;
+ }
+
+ firmware = fw_entry->data;
+ firmware_size = fw_entry->size;
+#endif
switch (dec->model) {
case TTUSB_DEC2000T:
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
firmware = &dsp_dec2000t[0];
firmware_size = sizeof(dsp_dec2000t);
+#endif
firmware_csum = 0x1bc86100;
break;
case TTUSB_DEC3000S:
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
firmware = &dsp_dec3000s[0];
firmware_size = sizeof(dsp_dec3000s);
+#endif
firmware_csum = 0x00000000;
break;
}
@@ -896,7 +921,7 @@ static int ttusb_dec_boot_dsp(struct ttusb_dec *dec)
return result;
}
-static void ttusb_dec_init_stb(struct ttusb_dec *dec)
+static int ttusb_dec_init_stb(struct ttusb_dec *dec)
{
u8 c[COMMAND_PACKET_SIZE];
int c_length;
@@ -906,9 +931,14 @@ static void ttusb_dec_init_stb(struct ttusb_dec *dec)
result = ttusb_dec_send_command(dec, 0x08, 0, NULL, &c_length, c);
- if (!result)
+ if (!result) {
if (c_length != 0x0c || (c_length == 0x0c && c[9] != 0x63))
- ttusb_dec_boot_dsp(dec);
+ return ttusb_dec_boot_dsp(dec);
+ else
+ return 0;
+ }
+ else
+ return result;
}
static int ttusb_dec_init_dvb(struct ttusb_dec *dec)
@@ -1309,6 +1339,8 @@ static int ttusb_dec_probe(struct usb_interface *intf,
printk("%s: couldn't allocate memory.\n", __FUNCTION__);
return -ENOMEM;
}
+
+ usb_set_intfdata(intf, (void *)dec);
#endif
memset(dec, 0, sizeof(struct ttusb_dec));
@@ -1317,27 +1349,33 @@ static int ttusb_dec_probe(struct usb_interface *intf,
case 0x1006:
dec->model = TTUSB_DEC3000S;
dec->model_name = "DEC3000-s";
+ dec->firmware_name = "dec3000s.bin";
break;
case 0x1008:
dec->model = TTUSB_DEC2000T;
dec->model_name = "DEC2000-t";
+ dec->firmware_name = "dec2000t.bin";
break;
}
dec->udev = udev;
ttusb_dec_init_usb(dec);
- ttusb_dec_init_stb(dec);
+ if (ttusb_dec_init_stb(dec)) {
+ ttusb_dec_exit_usb(dec);
+ return 0;
+ }
ttusb_dec_init_dvb(dec);
ttusb_dec_init_frontend(dec);
ttusb_dec_init_v_pes(dec);
ttusb_dec_init_tasklet(dec);
+ dec->active = 1;
+
#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
return (void *)dec;
#else
- usb_set_intfdata(intf, (void *)dec);
ttusb_dec_set_streaming_interface(dec);
return 0;
@@ -1358,10 +1396,12 @@ static void ttusb_dec_disconnect(struct usb_interface *intf)
dprintk("%s\n", __FUNCTION__);
- ttusb_dec_exit_tasklet(dec);
- ttusb_dec_exit_usb(dec);
- ttusb_dec_exit_frontend(dec);
- ttusb_dec_exit_dvb(dec);
+ if (dec->active) {
+ ttusb_dec_exit_tasklet(dec);
+ ttusb_dec_exit_usb(dec);
+ ttusb_dec_exit_frontend(dec);
+ ttusb_dec_exit_dvb(dec);
+ }
kfree(dec);
}