Commit b8bd49a4 authored by Michael Hunold's avatar Michael Hunold Committed by Linus Torvalds

[PATCH] DVB: Misc. DVB USB driver updates

 - [DVB] ttusb-dec:
   - Add a parameter to dvb_filter_pes2ts function to specify whether
     the packet is a payload unit start or not
   - Use the hotplug firmware loader for 2.6 kernels instead of
     compiling the firmware into the module. 
   - Correct the USB id of the DEC3000-s, add basic support

 - [DVB] ttusb-budget:
    - Remove spurious discontinuity message when starting streaming
parent 76aec2dc
...@@ -9,7 +9,6 @@ ...@@ -9,7 +9,6 @@
* published by the Free Software Foundation; either version 2 of * published by the Free Software Foundation; either version 2 of
* the License, or (at your option) any later version. * the License, or (at your option) any later version.
*/ */
#include <linux/version.h>
#include <linux/init.h> #include <linux/init.h>
#include <linux/slab.h> #include <linux/slab.h>
#include <linux/wait.h> #include <linux/wait.h>
...@@ -108,9 +107,10 @@ struct ttusb { ...@@ -108,9 +107,10 @@ struct ttusb {
int insync; int insync;
u16 cc; /* MuxCounter - will increment on EVERY MUX PACKET */ int cc; /* MuxCounter - will increment on EVERY MUX PACKET */
/* (including stuffing. yes. really.) */ /* (including stuffing. yes. really.) */
u8 last_result[32]; u8 last_result[32];
struct ttusb_channel { struct ttusb_channel {
...@@ -575,7 +575,7 @@ static void ttusb_process_muxpack(struct ttusb *ttusb, const u8 * muxpack, ...@@ -575,7 +575,7 @@ static void ttusb_process_muxpack(struct ttusb *ttusb, const u8 * muxpack,
cc = (muxpack[len - 4] << 8) | muxpack[len - 3]; cc = (muxpack[len - 4] << 8) | muxpack[len - 3];
cc &= 0x7FFF; cc &= 0x7FFF;
if (cc != ttusb->cc) if ((cc != ttusb->cc) && (ttusb->cc != -1))
printk("%s: cc discontinuity (%d frames missing)\n", printk("%s: cc discontinuity (%d frames missing)\n",
__FUNCTION__, (cc - ttusb->cc) & 0x7FFF); __FUNCTION__, (cc - ttusb->cc) & 0x7FFF);
ttusb->cc = (cc + 1) & 0x7FFF; ttusb->cc = (cc + 1) & 0x7FFF;
...@@ -787,7 +787,7 @@ static void ttusb_iso_irq(struct urb *urb, struct pt_regs *ptregs) ...@@ -787,7 +787,7 @@ static void ttusb_iso_irq(struct urb *urb, struct pt_regs *ptregs)
ttusb_process_frame(ttusb, data, len); ttusb_process_frame(ttusb, data, len);
} }
} }
usb_submit_urb(urb, GFP_ATOMIC); usb_submit_urb(urb, GFP_KERNEL);
} }
static void ttusb_free_iso_urbs(struct ttusb *ttusb) static void ttusb_free_iso_urbs(struct ttusb *ttusb)
...@@ -852,6 +852,7 @@ static int ttusb_start_iso_xfer(struct ttusb *ttusb) ...@@ -852,6 +852,7 @@ static int ttusb_start_iso_xfer(struct ttusb *ttusb)
return 0; return 0;
} }
ttusb->cc = -1;
ttusb->insync = 0; ttusb->insync = 0;
ttusb->mux_state = 0; ttusb->mux_state = 0;
...@@ -864,6 +865,7 @@ static int ttusb_start_iso_xfer(struct ttusb *ttusb) ...@@ -864,6 +865,7 @@ static int ttusb_start_iso_xfer(struct ttusb *ttusb)
urb->complete = ttusb_iso_irq; urb->complete = ttusb_iso_irq;
urb->pipe = ttusb->isoc_in_pipe; urb->pipe = ttusb->isoc_in_pipe;
urb->transfer_flags = URB_ISO_ASAP; urb->transfer_flags = URB_ISO_ASAP;
urb->interval = 1;
urb->number_of_packets = FRAMES_PER_ISO_BUF; urb->number_of_packets = FRAMES_PER_ISO_BUF;
urb->transfer_buffer_length = urb->transfer_buffer_length =
ISO_FRAME_SIZE * FRAMES_PER_ISO_BUF; ISO_FRAME_SIZE * FRAMES_PER_ISO_BUF;
...@@ -1008,7 +1010,6 @@ static int ttusb_stop_feed(struct dvb_demux_feed *dvbdmxfeed) ...@@ -1008,7 +1010,6 @@ static int ttusb_stop_feed(struct dvb_demux_feed *dvbdmxfeed)
static int ttusb_setup_interfaces(struct ttusb *ttusb) static int ttusb_setup_interfaces(struct ttusb *ttusb)
{ {
usb_set_configuration(ttusb->dev, 1);
usb_set_interface(ttusb->dev, 1, 1); usb_set_interface(ttusb->dev, 1, 1);
ttusb->bulk_out_pipe = usb_sndbulkpipe(ttusb->dev, 1); ttusb->bulk_out_pipe = usb_sndbulkpipe(ttusb->dev, 1);
...@@ -1077,6 +1078,8 @@ static int ttusb_probe(struct usb_interface *intf, const struct usb_device_id *i ...@@ -1077,6 +1078,8 @@ static int ttusb_probe(struct usb_interface *intf, const struct usb_device_id *i
udev = interface_to_usbdev(intf); udev = interface_to_usbdev(intf);
if (intf->altsetting->desc.bInterfaceNumber != 1) return -ENODEV;
if (!(ttusb = kmalloc(sizeof(struct ttusb), GFP_KERNEL))) if (!(ttusb = kmalloc(sizeof(struct ttusb), GFP_KERNEL)))
return -ENOMEM; return -ENOMEM;
...@@ -1101,8 +1104,7 @@ static int ttusb_probe(struct usb_interface *intf, const struct usb_device_id *i ...@@ -1101,8 +1104,7 @@ static int ttusb_probe(struct usb_interface *intf, const struct usb_device_id *i
up(&ttusb->sem); up(&ttusb->sem);
dvb_register_adapter(&ttusb->adapter, dvb_register_adapter(&ttusb->adapter, "Technotrend/Hauppauge Nova-USB", THIS_MODULE);
"Technotrend/Hauppauge Nova-USB");
dvb_register_i2c_bus(ttusb_i2c_xfer, ttusb, ttusb->adapter, 0); dvb_register_i2c_bus(ttusb_i2c_xfer, ttusb, ttusb->adapter, 0);
dvb_add_frontend_ioctls(ttusb->adapter, ttusb_lnb_ioctl, NULL, dvb_add_frontend_ioctls(ttusb->adapter, ttusb_lnb_ioctl, NULL,
...@@ -1169,9 +1171,6 @@ static void ttusb_disconnect(struct usb_interface *intf) ...@@ -1169,9 +1171,6 @@ static void ttusb_disconnect(struct usb_interface *intf)
ttusb_stop_iso_xfer(ttusb); ttusb_stop_iso_xfer(ttusb);
#if 0
devfs_remove(TTUSB_BUDGET_NAME);
#endif
ttusb->dvb_demux.dmx.close(&ttusb->dvb_demux.dmx); ttusb->dvb_demux.dmx.close(&ttusb->dvb_demux.dmx);
dvb_net_release(&ttusb->dvbnet); dvb_net_release(&ttusb->dvbnet);
dvb_dmxdev_release(&ttusb->dmxdev); dvb_dmxdev_release(&ttusb->dmxdev);
......
/* /*
* TTUSB DEC Driver * TTUSB DEC Driver
* *
* Copyright (C) 2003 Alex Woods <linux-dvb@giblets.org> * Copyright (C) 2003-2004 Alex Woods <linux-dvb@giblets.org>
* *
* This program is free software; you can redistribute it and/or modify * This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by * it under the terms of the GNU General Public License as published by
...@@ -20,16 +20,19 @@ ...@@ -20,16 +20,19 @@
*/ */
#include <asm/semaphore.h> #include <asm/semaphore.h>
#include <linux/crc32.h>
#include <linux/list.h> #include <linux/list.h>
#include <linux/module.h> #include <linux/module.h>
#include <linux/pci.h> #include <linux/pci.h>
#include <linux/slab.h> #include <linux/slab.h>
#include <linux/spinlock.h> #include <linux/spinlock.h>
#include <linux/usb.h> #include <linux/usb.h>
#include <linux/version.h>
#include <linux/interrupt.h> #include <linux/interrupt.h>
#include <linux/firmware.h> #include <linux/firmware.h>
#if defined(CONFIG_CRC32) || defined(CONFIG_CRC32_MODULE)
#include <linux/crc32.h>
#else
#warning "CRC checking of firmware not available"
#endif
#include <linux/init.h> #include <linux/init.h>
#include "dmxdev.h" #include "dmxdev.h"
...@@ -99,6 +102,7 @@ struct ttusb_dec { ...@@ -99,6 +102,7 @@ struct ttusb_dec {
u16 pid[DMX_PES_OTHER]; u16 pid[DMX_PES_OTHER];
int hi_band; int hi_band;
int voltage;
/* USB bits */ /* USB bits */
struct usb_device *udev; struct usb_device *udev;
...@@ -205,22 +209,15 @@ static int ttusb_dec_send_command(struct ttusb_dec *dec, const u8 command, ...@@ -205,22 +209,15 @@ static int ttusb_dec_send_command(struct ttusb_dec *dec, const u8 command,
{ {
int result, actual_len, i; int result, actual_len, i;
u8 *b; u8 *b;
u8 *c;
dprintk("%s\n", __FUNCTION__);
b = kmalloc(COMMAND_PACKET_SIZE + 4, GFP_KERNEL); b = kmalloc(COMMAND_PACKET_SIZE + 4, GFP_KERNEL);
if (!b) if (!b)
return -ENOMEM; return -ENOMEM;
c = kmalloc(COMMAND_PACKET_SIZE + 4, GFP_KERNEL);
if (!c) {
kfree(b);
return -ENOMEM;
}
dprintk("%s\n", __FUNCTION__);
if ((result = down_interruptible(&dec->usb_sem))) { if ((result = down_interruptible(&dec->usb_sem))) {
kfree(b); kfree(b);
kfree(c);
printk("%s: Failed to down usb semaphore.\n", __FUNCTION__); printk("%s: Failed to down usb semaphore.\n", __FUNCTION__);
return result; return result;
} }
...@@ -248,11 +245,10 @@ static int ttusb_dec_send_command(struct ttusb_dec *dec, const u8 command, ...@@ -248,11 +245,10 @@ static int ttusb_dec_send_command(struct ttusb_dec *dec, const u8 command,
__FUNCTION__, result); __FUNCTION__, result);
up(&dec->usb_sem); up(&dec->usb_sem);
kfree(b); kfree(b);
kfree(c);
return result; return result;
} }
result = usb_bulk_msg(dec->udev, dec->result_pipe, c, result = usb_bulk_msg(dec->udev, dec->result_pipe, b,
COMMAND_PACKET_SIZE + 4, &actual_len, HZ); COMMAND_PACKET_SIZE + 4, &actual_len, HZ);
if (result) { if (result) {
...@@ -260,25 +256,23 @@ static int ttusb_dec_send_command(struct ttusb_dec *dec, const u8 command, ...@@ -260,25 +256,23 @@ static int ttusb_dec_send_command(struct ttusb_dec *dec, const u8 command,
__FUNCTION__, result); __FUNCTION__, result);
up(&dec->usb_sem); up(&dec->usb_sem);
kfree(b); kfree(b);
kfree(c);
return result; return result;
} else { } else {
if (debug) { if (debug) {
printk("%s: result: ", __FUNCTION__); printk("%s: result: ", __FUNCTION__);
for (i = 0; i < actual_len; i++) for (i = 0; i < actual_len; i++)
printk("0x%02X ", c[i]); printk("0x%02X ", b[i]);
printk("\n"); printk("\n");
} }
if (result_length) if (result_length)
*result_length = c[3]; *result_length = b[3];
if (cmd_result && c[3] > 0) if (cmd_result && b[3] > 0)
memcpy(cmd_result, &c[4], c[3]); memcpy(cmd_result, &b[4], b[3]);
up(&dec->usb_sem); up(&dec->usb_sem);
kfree(b); kfree(b);
kfree(c);
return 0; return 0;
} }
} }
...@@ -1171,9 +1165,10 @@ static int ttusb_dec_boot_dsp(struct ttusb_dec *dec) ...@@ -1171,9 +1165,10 @@ static int ttusb_dec_boot_dsp(struct ttusb_dec *dec)
u16 firmware_csum = 0; u16 firmware_csum = 0;
u16 firmware_csum_ns; u16 firmware_csum_ns;
u32 firmware_size_nl; u32 firmware_size_nl;
#if defined(CONFIG_CRC32) || defined(CONFIG_CRC32_MODULE)
u32 crc32_csum, crc32_check, tmp; u32 crc32_csum, crc32_check, tmp;
#endif
const struct firmware *fw_entry = NULL; const struct firmware *fw_entry = NULL;
dprintk("%s\n", __FUNCTION__); dprintk("%s\n", __FUNCTION__);
if (request_firmware(&fw_entry, dec->firmware_name, &dec->udev->dev)) { if (request_firmware(&fw_entry, dec->firmware_name, &dec->udev->dev)) {
...@@ -1186,7 +1181,7 @@ static int ttusb_dec_boot_dsp(struct ttusb_dec *dec) ...@@ -1186,7 +1181,7 @@ static int ttusb_dec_boot_dsp(struct ttusb_dec *dec)
firmware_size = fw_entry->size; firmware_size = fw_entry->size;
if (firmware_size < 60) { if (firmware_size < 60) {
printk("%s: firmware size too small for DSP code (%zu < 60).\n", printk("%s: firmware size too small for DSP code (%u < 60).\n",
__FUNCTION__, firmware_size); __FUNCTION__, firmware_size);
return -1; return -1;
} }
...@@ -1194,6 +1189,7 @@ static int ttusb_dec_boot_dsp(struct ttusb_dec *dec) ...@@ -1194,6 +1189,7 @@ static int ttusb_dec_boot_dsp(struct ttusb_dec *dec)
/* a 32 bit checksum over the first 56 bytes of the DSP Code is stored /* a 32 bit checksum over the first 56 bytes of the DSP Code is stored
at offset 56 of file, so use it to check if the firmware file is at offset 56 of file, so use it to check if the firmware file is
valid. */ valid. */
#if defined(CONFIG_CRC32) || defined(CONFIG_CRC32_MODULE)
crc32_csum = crc32(~0L, firmware, 56) ^ ~0L; crc32_csum = crc32(~0L, firmware, 56) ^ ~0L;
memcpy(&tmp, &firmware[56], 4); memcpy(&tmp, &firmware[56], 4);
crc32_check = htonl(tmp); crc32_check = htonl(tmp);
...@@ -1203,6 +1199,7 @@ static int ttusb_dec_boot_dsp(struct ttusb_dec *dec) ...@@ -1203,6 +1199,7 @@ static int ttusb_dec_boot_dsp(struct ttusb_dec *dec)
__FUNCTION__, crc32_csum, crc32_check); __FUNCTION__, crc32_csum, crc32_check);
return -1; return -1;
} }
#endif
memcpy(idstring, &firmware[36], 20); memcpy(idstring, &firmware[36], 20);
idstring[20] = '\0'; idstring[20] = '\0';
printk(KERN_INFO "ttusb_dec: found DSP code \"%s\".\n", idstring); printk(KERN_INFO "ttusb_dec: found DSP code \"%s\".\n", idstring);
...@@ -1287,6 +1284,7 @@ static int ttusb_dec_init_stb(struct ttusb_dec *dec) ...@@ -1287,6 +1284,7 @@ static int ttusb_dec_init_stb(struct ttusb_dec *dec)
give the box */ give the box */
switch (model) { switch (model) {
case 0x00070008: case 0x00070008:
case 0x0007000c:
ttusb_dec_set_model(dec, TTUSB_DEC3000S); ttusb_dec_set_model(dec, TTUSB_DEC3000S);
break; break;
case 0x00070009: case 0x00070009:
...@@ -1320,7 +1318,7 @@ static int ttusb_dec_init_dvb(struct ttusb_dec *dec) ...@@ -1320,7 +1318,7 @@ static int ttusb_dec_init_dvb(struct ttusb_dec *dec)
dprintk("%s\n", __FUNCTION__); dprintk("%s\n", __FUNCTION__);
if ((result = dvb_register_adapter(&dec->adapter, if ((result = dvb_register_adapter(&dec->adapter,
dec->model_name)) < 0) { dec->model_name, THIS_MODULE)) < 0) {
printk("%s: dvb_register_adapter failed: error %d\n", printk("%s: dvb_register_adapter failed: error %d\n",
__FUNCTION__, result); __FUNCTION__, result);
...@@ -1518,10 +1516,6 @@ static int ttusb_dec_2000t_frontend_ioctl(struct dvb_frontend *fe, unsigned int ...@@ -1518,10 +1516,6 @@ static int ttusb_dec_2000t_frontend_ioctl(struct dvb_frontend *fe, unsigned int
dprintk("%s: FE_INIT\n", __FUNCTION__); dprintk("%s: FE_INIT\n", __FUNCTION__);
break; break;
case FE_RESET:
dprintk("%s: FE_RESET\n", __FUNCTION__);
break;
default: default:
dprintk("%s: unknown IOCTL (0x%X)\n", __FUNCTION__, cmd); dprintk("%s: unknown IOCTL (0x%X)\n", __FUNCTION__, cmd);
return -EINVAL; return -EINVAL;
...@@ -1591,13 +1585,13 @@ static int ttusb_dec_3000s_frontend_ioctl(struct dvb_frontend *fe, ...@@ -1591,13 +1585,13 @@ static int ttusb_dec_3000s_frontend_ioctl(struct dvb_frontend *fe,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x0d, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00 }; 0x00, 0x00, 0x00, 0x00 };
u32 freq; u32 freq;
u32 sym_rate; u32 sym_rate;
u32 band; u32 band;
u32 lnb_voltage;
dprintk("%s: FE_SET_FRONTEND\n", __FUNCTION__); dprintk("%s: FE_SET_FRONTEND\n", __FUNCTION__);
...@@ -1613,6 +1607,8 @@ static int ttusb_dec_3000s_frontend_ioctl(struct dvb_frontend *fe, ...@@ -1613,6 +1607,8 @@ static int ttusb_dec_3000s_frontend_ioctl(struct dvb_frontend *fe,
memcpy(&b[12], &sym_rate, sizeof(u32)); memcpy(&b[12], &sym_rate, sizeof(u32));
band = htonl(dec->hi_band ? LOF_HI : LOF_LO); band = htonl(dec->hi_band ? LOF_HI : LOF_LO);
memcpy(&b[24], &band, sizeof(u32)); memcpy(&b[24], &band, sizeof(u32));
lnb_voltage = htonl(dec->voltage);
memcpy(&b[28], &lnb_voltage, sizeof(u32));
ttusb_dec_send_command(dec, 0x71, sizeof(b), b, NULL, NULL); ttusb_dec_send_command(dec, 0x71, sizeof(b), b, NULL, NULL);
...@@ -1632,10 +1628,6 @@ static int ttusb_dec_3000s_frontend_ioctl(struct dvb_frontend *fe, ...@@ -1632,10 +1628,6 @@ static int ttusb_dec_3000s_frontend_ioctl(struct dvb_frontend *fe,
dprintk("%s: FE_INIT\n", __FUNCTION__); dprintk("%s: FE_INIT\n", __FUNCTION__);
break; break;
case FE_RESET:
dprintk("%s: FE_RESET\n", __FUNCTION__);
break;
case FE_DISEQC_SEND_MASTER_CMD: case FE_DISEQC_SEND_MASTER_CMD:
dprintk("%s: FE_DISEQC_SEND_MASTER_CMD\n", __FUNCTION__); dprintk("%s: FE_DISEQC_SEND_MASTER_CMD\n", __FUNCTION__);
break; break;
...@@ -1653,6 +1645,17 @@ static int ttusb_dec_3000s_frontend_ioctl(struct dvb_frontend *fe, ...@@ -1653,6 +1645,17 @@ static int ttusb_dec_3000s_frontend_ioctl(struct dvb_frontend *fe,
case FE_SET_VOLTAGE: case FE_SET_VOLTAGE:
dprintk("%s: FE_SET_VOLTAGE\n", __FUNCTION__); dprintk("%s: FE_SET_VOLTAGE\n", __FUNCTION__);
switch ((fe_sec_voltage_t) arg) {
case SEC_VOLTAGE_13:
dec->voltage = 13;
break;
case SEC_VOLTAGE_18:
dec->voltage = 18;
break;
default:
return -EINVAL;
break;
}
break; break;
default: default:
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment