*
*/
-#include <asm/semaphore.h>
+#include <linux/mutex.h>
+
#include <linux/list.h>
#include <linux/module.h>
#include <linux/moduleparam.h>
#include <linux/slab.h>
#include <linux/spinlock.h>
#include <linux/usb.h>
-#include <linux/version.h>
#include <linux/interrupt.h>
#include <linux/firmware.h>
#include <linux/crc32.h>
unsigned int out_pipe;
unsigned int irq_pipe;
enum ttusb_dec_interface interface;
- struct semaphore usb_sem;
+ struct mutex usb_mutex;
void *irq_buffer;
struct urb *irq_urb;
dma_addr_t iso_dma_handle;
struct urb *iso_urb[ISO_BUF_COUNT];
int iso_stream_count;
- struct semaphore iso_sem;
+ struct mutex iso_mutex;
u8 packet[MAX_PVA_LENGTH + 4];
enum ttusb_dec_packet_type packet_type;
struct list_head filter_info_list;
spinlock_t filter_info_list_lock;
- struct input_dev rc_input_dev;
+ struct input_dev *rc_input_dev;
+ char rc_phys[64];
int active; /* Loaded successfully */
};
* this should/could be added later ...
* for now lets report each signal as a key down and up*/
dprintk("%s:rc signal:%d\n", __FUNCTION__, buffer[4]);
- input_report_key(&dec->rc_input_dev,rc_keys[buffer[4]-1],1);
- input_report_key(&dec->rc_input_dev,rc_keys[buffer[4]-1],0);
- input_sync(&dec->rc_input_dev);
+ input_report_key(dec->rc_input_dev, rc_keys[buffer[4] - 1], 1);
+ input_report_key(dec->rc_input_dev, rc_keys[buffer[4] - 1], 0);
+ input_sync(dec->rc_input_dev);
}
exit: retval = usb_submit_urb(urb, GFP_ATOMIC);
if (!b)
return -ENOMEM;
- if ((result = down_interruptible(&dec->usb_sem))) {
+ if ((result = mutex_lock_interruptible(&dec->usb_mutex))) {
kfree(b);
- printk("%s: Failed to down usb semaphore.\n", __FUNCTION__);
+ printk("%s: Failed to lock usb mutex.\n", __FUNCTION__);
return result;
}
if (result) {
printk("%s: command bulk message failed: error %d\n",
__FUNCTION__, result);
- up(&dec->usb_sem);
+ mutex_unlock(&dec->usb_mutex);
kfree(b);
return result;
}
if (result) {
printk("%s: result bulk message failed: error %d\n",
__FUNCTION__, result);
- up(&dec->usb_sem);
+ mutex_unlock(&dec->usb_mutex);
kfree(b);
return result;
} else {
if (cmd_result && b[3] > 0)
memcpy(cmd_result, &b[4], b[3]);
- up(&dec->usb_sem);
+ mutex_unlock(&dec->usb_mutex);
kfree(b);
return 0;
static int ttusb_dec_audio_pes2ts_cb(void *priv, unsigned char *data)
{
- struct ttusb_dec *dec = (struct ttusb_dec *)priv;
+ struct ttusb_dec *dec = priv;
dec->audio_filter->feed->cb.ts(data, 188, NULL, 0,
&dec->audio_filter->feed->feed.ts,
static int ttusb_dec_video_pes2ts_cb(void *priv, unsigned char *data)
{
- struct ttusb_dec *dec = (struct ttusb_dec *)priv;
+ struct ttusb_dec *dec = priv;
dec->video_filter->feed->cb.ts(data, 188, NULL, 0,
&dec->video_filter->feed->feed.ts,
dprintk("%s\n", __FUNCTION__);
- if (down_interruptible(&dec->iso_sem))
+ if (mutex_lock_interruptible(&dec->iso_mutex))
return;
dec->iso_stream_count--;
usb_kill_urb(dec->iso_urb[i]);
}
- up(&dec->iso_sem);
+ mutex_unlock(&dec->iso_mutex);
}
/* Setting the interface of the DEC tends to take down the USB communications
dprintk("%s\n", __FUNCTION__);
- if (down_interruptible(&dec->iso_sem))
+ if (mutex_lock_interruptible(&dec->iso_mutex))
return -EAGAIN;
if (!dec->iso_stream_count) {
i--;
}
- up(&dec->iso_sem);
+ mutex_unlock(&dec->iso_mutex);
return result;
}
}
dec->iso_stream_count++;
- up(&dec->iso_sem);
+ mutex_unlock(&dec->iso_mutex);
return 0;
}
case DMX_TS_PES_TELETEXT:
dec->pid[DMX_PES_TELETEXT] = dvbdmxfeed->pid;
- dprintk(" pes_type: DMX_TS_PES_TELETEXT\n");
- break;
+ dprintk(" pes_type: DMX_TS_PES_TELETEXT(not supported)\n");
+ return -ENOSYS;
case DMX_TS_PES_PCR:
dprintk(" pes_type: DMX_TS_PES_PCR\n");
break;
case DMX_TS_PES_OTHER:
- dprintk(" pes_type: DMX_TS_PES_OTHER\n");
- break;
+ dprintk(" pes_type: DMX_TS_PES_OTHER(not supported)\n");
+ return -ENOSYS;
default:
dprintk(" pes_type: unknown (%d)\n", dvbdmxfeed->pes_type);
(unsigned long)dec);
}
-static void ttusb_init_rc( struct ttusb_dec *dec)
+static int ttusb_init_rc( struct ttusb_dec *dec)
{
+ struct input_dev *input_dev;
u8 b[] = { 0x00, 0x01 };
int i;
- init_input_dev(&dec->rc_input_dev);
+ usb_make_path(dec->udev, dec->rc_phys, sizeof(dec->rc_phys));
+ strlcpy(dec->rc_phys, "/input0", sizeof(dec->rc_phys));
- dec->rc_input_dev.name = "ttusb_dec remote control";
- dec->rc_input_dev.evbit[0] = BIT(EV_KEY);
- dec->rc_input_dev.keycodesize = sizeof(u16);
- dec->rc_input_dev.keycodemax = 0x1a;
- dec->rc_input_dev.keycode = rc_keys;
+ dec->rc_input_dev = input_dev = input_allocate_device();
+ if (!input_dev)
+ return -ENOMEM;
- for (i = 0; i < sizeof(rc_keys)/sizeof(rc_keys[0]); i++)
- set_bit(rc_keys[i], dec->rc_input_dev.keybit);
+ input_dev->name = "ttusb_dec remote control";
+ input_dev->phys = dec->rc_phys;
+ input_dev->evbit[0] = BIT(EV_KEY);
+ input_dev->keycodesize = sizeof(u16);
+ input_dev->keycodemax = 0x1a;
+ input_dev->keycode = rc_keys;
- input_register_device(&dec->rc_input_dev);
+ for (i = 0; i < ARRAY_SIZE(rc_keys); i++)
+ set_bit(rc_keys[i], input_dev->keybit);
- if(usb_submit_urb(dec->irq_urb,GFP_KERNEL)) {
+ input_register_device(input_dev);
+
+ if (usb_submit_urb(dec->irq_urb, GFP_KERNEL))
printk("%s: usb_submit_urb failed\n",__FUNCTION__);
- }
/* enable irq pipe */
ttusb_dec_send_command(dec,0xb0,sizeof(b),b,NULL,NULL);
+
+ return 0;
}
static void ttusb_dec_init_v_pes(struct ttusb_dec *dec)
{
dprintk("%s\n", __FUNCTION__);
- sema_init(&dec->usb_sem, 1);
- sema_init(&dec->iso_sem, 1);
+ mutex_init(&dec->usb_mutex);
+ mutex_init(&dec->iso_mutex);
dec->command_pipe = usb_sndbulkpipe(dec->udev, COMMAND_PIPE);
dec->result_pipe = usb_rcvbulkpipe(dec->udev, RESULT_PIPE);
if (firmware_size < 60) {
printk("%s: firmware size too small for DSP code (%zu < 60).\n",
__FUNCTION__, firmware_size);
+ release_firmware(fw_entry);
return -1;
}
printk("%s: crc32 check of DSP code failed (calculated "
"0x%08x != 0x%08x in file), file invalid.\n",
__FUNCTION__, crc32_csum, crc32_check);
+ release_firmware(fw_entry);
return -1;
}
memcpy(idstring, &firmware[36], 20);
result = ttusb_dec_send_command(dec, 0x41, sizeof(b0), b0, NULL, NULL);
- if (result)
+ if (result) {
+ release_firmware(fw_entry);
return result;
+ }
trans_count = 0;
j = 0;
b = kmalloc(ARM_PACKET_SIZE, GFP_KERNEL);
- if (b == NULL)
+ if (b == NULL) {
+ release_firmware(fw_entry);
return -ENOMEM;
+ }
for (i = 0; i < firmware_size; i += COMMAND_PACKET_SIZE) {
size = firmware_size - i;
result = ttusb_dec_send_command(dec, 0x43, sizeof(b1), b1, NULL, NULL);
+ release_firmware(fw_entry);
kfree(b);
return result;
/* We can't trust the USB IDs that some firmwares
give the box */
switch (model) {
+ case 0x00070001:
case 0x00070008:
case 0x0007000c:
ttusb_dec_set_model(dec, TTUSB_DEC3000S);
* As the irq is submitted after the interface is changed,
* this is the best method i figured out.
* Any others?*/
- if(dec->interface == TTUSB_DEC_INTERFACE_IN)
+ if (dec->interface == TTUSB_DEC_INTERFACE_IN)
usb_kill_urb(dec->irq_urb);
usb_free_urb(dec->irq_urb);
usb_buffer_free(dec->udev,IRQ_PACKET_SIZE,
- dec->irq_buffer, dec->irq_dma_handle);
+ dec->irq_buffer, dec->irq_dma_handle);
- input_unregister_device(&dec->rc_input_dev);
+ if (dec->rc_input_dev) {
+ input_unregister_device(dec->rc_input_dev);
+ dec->rc_input_dev = NULL;
+ }
}
int param_length, const u8 params[],
int *result_length, u8 cmd_result[])
{
- struct ttusb_dec* dec = (struct ttusb_dec*) fe->dvb->priv;
+ struct ttusb_dec* dec = fe->dvb->priv;
return ttusb_dec_send_command(dec, command, param_length, params, result_length, cmd_result);
}
udev = interface_to_usbdev(intf);
- if (!(dec = kmalloc(sizeof(struct ttusb_dec), GFP_KERNEL))) {
+ if (!(dec = kzalloc(sizeof(struct ttusb_dec), GFP_KERNEL))) {
printk("%s: couldn't allocate memory.\n", __FUNCTION__);
return -ENOMEM;
}
usb_set_intfdata(intf, (void *)dec);
- memset(dec, 0, sizeof(struct ttusb_dec));
-
switch (le16_to_cpu(id->idProduct)) {
case 0x1006:
ttusb_dec_set_model(dec, TTUSB_DEC3000S);
ttusb_dec_set_interface(dec, TTUSB_DEC_INTERFACE_IN);
- if(enable_rc)
+ if (enable_rc)
ttusb_init_rc(dec);
return 0;