summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--linux/drivers/media/dvb/vp7041/Kconfig18
-rw-r--r--linux/drivers/media/dvb/vp7041/Makefile3
-rw-r--r--linux/drivers/media/dvb/vp7041/vp7041.c1038
3 files changed, 0 insertions, 1059 deletions
diff --git a/linux/drivers/media/dvb/vp7041/Kconfig b/linux/drivers/media/dvb/vp7041/Kconfig
deleted file mode 100644
index 757b3e434..000000000
--- a/linux/drivers/media/dvb/vp7041/Kconfig
+++ /dev/null
@@ -1,18 +0,0 @@
-config DVB_VP7041
- tristate "Twinhan Visionplus USB-Ter DVB-T/CTS Portable"
- depends on DVB_CORE && USB
- select FW_LOADER
- help
- Support for the external USB adapter made by Twinhan (and maybe others)
- which is called "Twinhan Visionplus VisionDTV USB-Ter" and seems to
- be identical to "CTS Portable" (Chinese Television System).
-
- These devices can be understood as budget ones, they only deliver
- the MPEG data.
-
- This driver needs external firmware. Please use the command
- "<kerneldir>/Documentation/dvb/get_dvb_firmware vp7041" to
- download/extract it, and then copy it to /usr/lib/hotplug/firmware.
-
- Say Y if you own such a device and want to use it. You should build it as
- a module.
diff --git a/linux/drivers/media/dvb/vp7041/Makefile b/linux/drivers/media/dvb/vp7041/Makefile
deleted file mode 100644
index 39c0dd9a4..000000000
--- a/linux/drivers/media/dvb/vp7041/Makefile
+++ /dev/null
@@ -1,3 +0,0 @@
-obj-$(CONFIG_DVB_VP7041) += vp7041.o
-
-EXTRA_CFLAGS = -Idrivers/media/dvb/dvb-core/
diff --git a/linux/drivers/media/dvb/vp7041/vp7041.c b/linux/drivers/media/dvb/vp7041/vp7041.c
deleted file mode 100644
index 9742d97d9..000000000
--- a/linux/drivers/media/dvb/vp7041/vp7041.c
+++ /dev/null
@@ -1,1038 +0,0 @@
-/*
- * Driver for
- *
- * Twinhan VisionPlus VisionDTV USB-Ter DVB-T Device (VP7041)
- * CTS Portable (Chinese Television System)
- *
- * http://www.twinhan.com/visiontv-2_4.htm
- * http://www.2cts.tv/ctsportable/
- *
- * This driver should also work with the CTS Portable since the
- * windriver seems to be identical to the Twinhan one.
- *
- * vp7041.c
- *
- * Copyright (C) 2004 Patrick Boettcher (patrick.boettcher@desy.de),
- *
- * 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 the Free Software Foundation, version 2.
- *
- * Acknowledgements
- * Alex Woods for frequently answering question about usb and dvb
- * stuff
- *
- * Some guys on the linux-dvb mailing list for encouraging me
- *
- * Peter Schildmann >peter.schildmann-nospam-at-web.de< for his
- * user-level firmware loader, which saves a lot of time
- *
- * Ulf Hermenau for helping me out with traditional chinese.
- *
- * André Smoktun and Christian Frömmel
- *
- * Problem:
- * - when tzap is running and you replug the device, a deadlock occures
- * - disconnecting the device during mplayer is running brings a big oops
- * somehow a clean usb exit has to be done
- *
- * TODO:
- * - handling of USB disconnects (Oops when unplugged)
- * - check init end deinit methods
- * - different processor types (delays?)
- * - big/litte endian ?
- *
- */
-
-#include <linux/config.h>
-#include <linux/kernel.h>
-#include <linux/usb.h>
-#include <linux/firmware.h>
-#include <linux/pci.h>
-#include <linux/version.h>
-#include <linux/moduleparam.h>
-
-#include "dmxdev.h"
-#include "dvb_demux.h"
-#include "dvb_filter.h"
-#include "dvb_frontend.h"
-#include "dvb_net.h"
-
-static int debug;
-
-module_param(debug, int, 0x644);
-MODULE_PARM_DESC(debug, "Turn on/off debugging (default:off).");
-
-#define dprintk if (debug) printk
-
-/* Version information */
-#define DRIVER_VERSION "0.2"
-#define DRIVER_DESC "Twinhan VisionPlus VisionDTV USB-Ter DVB-T / CTS Portable"
-#define DRIVER_AUTHOR "Patrick Boettcher, patrick.boettcher@desy.de"
-
-#define USB_TWINHAN_VENDOR_ID 0x1822
-// product ID befode loading the firmware
-#define USB_VP7041_PRODUCT_PREFW_ID 0x3201
-// product ID afterwards
-#define USB_VP7041_PRODUCT_ID 0x3202
-
-/* USB Driver stuff */
-
-/* table of devices that work with this driver */
-static struct usb_device_id vp7041_table [] = {
- { USB_DEVICE(USB_TWINHAN_VENDOR_ID, USB_VP7041_PRODUCT_PREFW_ID) },
- { USB_DEVICE(USB_TWINHAN_VENDOR_ID, USB_VP7041_PRODUCT_ID) },
- { } /* Terminating entry */
-};
-
-MODULE_DEVICE_TABLE (usb, vp7041_table);
-
-static const char *firmware_filenames[] = {
- "dvb-vp7041-2.42.fw",
- "dvb-vp7041-2.422.fw"
-};
-
-#define COMMAND_PIPE 0x01
-#define RESULT_PIPE 0x81
-#define DATA_PIPE 0x82
-
-#define VP7041_MAX_PIDS 16
-
-struct vp7041_channel {
- struct usb_vp7041 *vp;
-
- u8 id;
- u16 pid;
- u8 active;
-};
-
-/* data struct */
-struct usb_vp7041 {
-/* usb */
- struct usb_device * udev;
-
- unsigned int command_pipe;
- unsigned int result_pipe;
- unsigned int data_pipe;
-
- struct urb *buf_urb;
- u8 *buffer;
- dma_addr_t dma_handle;
-
- struct vp7041_channel channel[VP7041_MAX_PIDS];
-
- fe_status_t fe_status;
- struct dvb_frontend_parameters fe_params;
- int feed_count;
- int streaming;
- int disconnecting;
-
- struct semaphore usb_sem;
- spinlock_t channel_lock;
-
-/* dvb */
- struct dvb_adapter *adapter;
- struct dmxdev dmxdev;
- struct dvb_demux demux;
- struct dvb_net dvb_net;
- struct dmx_frontend frontend;
-
-/* i2c */
- struct i2c_adapter *i2c;
-};
-
-static struct dvb_frontend_info vp7041_frontend_info = {
- .name = "VisionPlus VisionDTV USB-Ter (VP7041) Frontend",
- .type = FE_OFDM,
- .frequency_min = 40000000,
- .frequency_max = 858000000,
- .frequency_stepsize = 62500,
- .caps = FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4 |
- FE_CAN_FEC_5_6 | FE_CAN_FEC_7_8 | FE_CAN_FEC_AUTO |
- FE_CAN_QAM_16 | FE_CAN_QAM_64 | FE_CAN_QAM_AUTO |
- FE_CAN_TRANSMISSION_MODE_AUTO | FE_CAN_GUARD_INTERVAL_AUTO |
- FE_CAN_HIERARCHY_AUTO,
-};
-
-static u8 vp7041_init_buf[] = {
- 0x07, 0x00, 0x01, 0x33, 0x00, 0xc0, 0x80, 0x33, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x1c, 0x00, 0x00, 0x00, 0x86, 0xa0, 0xc2, 0x37, 0xf3, 0x24, 0xd2, 0x4e, 0x85,
- 0x01, 0xa1, 0xcd, 0x7e, 0x50, 0xbb, 0x08, 0x01
-};
-/* 2004-07-12
- 0x07, 0x00, 0x01, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-*/
-
-
-static int vp7041_cmdmsg(struct usb_vp7041 *vp,u8 *buf, unsigned int buflen,
- u8 *retbuf, unsigned int retbuflen, unsigned int *actbuflen)
-{
- u8 *b;
- int actual_size,ret = -ENOMEM;
-
- if (buf == NULL || buflen == 0)
- return -EINVAL;
-
- if (vp->disconnecting)
- return -EINVAL;
-
- if ((ret = down_interruptible(&vp->usb_sem))) {
- err("Failed to down usb semaphore.\n");
- return ret;
- }
-
- b = kmalloc(buflen,GFP_KERNEL);
- if (b) {
- memcpy(b,buf,buflen);
-
- if (debug) {
- int i;
- printk("%s: %d > ", __FUNCTION__,buflen);
- for (i = 0; i < buflen; i++)
- printk("%02x ", b[i]);
- printk("\n");
- }
-
- ret = usb_bulk_msg(vp->udev,vp->command_pipe,
- b,buflen,&actual_size,HZ);
-
- if (ret)
- err("bulk message failed: %d (%d/%d)",ret,buflen,actual_size);
- else
- ret = actual_size != buflen ? -1 : 0;
-
- kfree(b);
- }
-
- if (!ret && retbuf && retbuflen && actbuflen != NULL) {
- ret = usb_bulk_msg(vp->udev,vp->result_pipe,retbuf,
- retbuflen,actbuflen,HZ);
- if (ret)
- err("recv bulk message failed: %d",ret);
- else if (debug) {
- int i;
- printk("%s: %d/%d > ", __FUNCTION__,*actbuflen,retbuflen);
- for (i = 0; i < *actbuflen; i++)
- printk("%02x ", retbuf[i]);
- printk("\n");
- }
- }
-
- up(&vp->usb_sem);
-
- return ret;
-}
-
-static int vp7041_sndmsg(struct usb_vp7041 *vp,u8 *buf, unsigned int buflen)
-{
- return vp7041_cmdmsg(vp,buf,buflen,NULL,0,NULL);
-}
-
-static int vp7041_02_cmd(struct usb_vp7041 *vp, u8 a, u8 b, u8 c, u8 d, u8 e, u16 *val)
-{
- u8 buf[64],bin[6] = { 0x02, a, b, c, d, e };
- int ret,len;
-
- *val = 0;
- if ((ret = vp7041_cmdmsg(vp,bin,6,buf,64,&len)))
- return ret;
-
- if (len != 2) {
- err("unexpected return length: %d",len);
- return -ENOSYS;
- }
-
- *val = buf[0] << 8 | buf[1];
- dprintk("return stat: %d 0x%4x",*val,*val);
- return 0;
-}
-
-static int vp7041_03_cmd(struct usb_vp7041 *vp, u8 a, u8 b, u8 c, u8 d, u8 e)
-{
- u8 buf[6] = { 0x03, a, b, c, d, e };
- return vp7041_sndmsg(vp,buf,6);
-}
-
-static int vp7041_chk_tune (struct usb_vp7041 *vp,u8 stat, u16 *val)
-{
- return vp7041_02_cmd(vp,0x11,0x81,stat,0x00,0x02,val);
-}
-
-static int vp7041_tune(struct usb_vp7041 *vp, unsigned int freq, unsigned int bw)
-{
- u8 bwbuf[] = {
- 0x08,0x00, 0, 0x09, 0, 0,
- 0x37,0x00,0x00, 0x38,0x00, 0, 0x39, 0, 0, 0x3a,0x00, 0,
- 0x3b, 0, 0, 0x3c, 0, 0, 0x3d, 0, 0, 0x3e,0x00,0x00,
- 0x3f,0x03,0xe8, 0x40,0x00,0x00, 0x41,0x03,0xf2, 0x42,0x00,0x01,
- 0x43,0xb0,0xd0,
-
- 0x34,0x00,0x04, 0x01,0x00,0x01, 0x02,0x00,0x00,
- 0x05,0x00,0x01, 0x36,0x00,0x0b,
- 0x4f,0x00,0x01,
-
- 0x54,0x00,0x00, 0x79,0x00,0x05,
-
- 0xc3,0x00,0x01, 0x7e,0x00,0x00, 0x65,0x00,0x00,
-
- 0x2b,0x09,0x2d, 0x2c,0x00,0x05, 0x2d,0x09,0x2d, 0x2e,0x00,0x05,
- 0x2f,0x0a,0x1a, 0x30,0x00,0x02, 0x31,0x0a,0x1a, 0x32,0x00,0x02,
- 0x4f,0x00,0x00,
- 0x00,0x00,0x0c, 0x00,0x00,0x00,
-
- 0x2b,0x08,0x28, 0x2c,0x00,0x0a, 0x2d,0x08,0x28, 0x2e,0x00,0x0a,
- 0x2f,0x0d,0x78, 0x30,0x00,0x05, 0x31,0x0d,0x78, 0x32,0x00,0x05,
- 0x4f,0x00,0x01,
-
- 0x00,0x00,0x02, 0x00,0x00,0x00
- };
- u8 prefeedbuf[] = {
- 0x81,0x53, 0x81,0x54, 0x80,0x06, 0x80,0x07, 0x81,0x8e, 0x81,0x8f,
- 0x81,0x90, 0x81,0x91, 0x81,0x92, 0x81,0x93, 0x81,0x94
- };
- u8 prefeedbuf2[] = {
- 0x34,0x00,0x04, 0x01,0x00,0x01, 0x02,0x00,0x02,
- 0x05,0x00,0x01, 0x36,0x00,0x00, 0x4f,0x00,0x00,
- 0x54,0x00,0x00, 0x79,0x00,0x05,
-
- 0x03,0x00,0x01,
- 0x04,0x00,0x01, 0x82,0x00,0x01, 0x81,0x00,0x02,
-
- 0xc3,0x00,0x01, 0x7e,0x00,0x00, 0x65,0x00,0x00,
- 0x00,0x00,0x04, 0x00,0x00,0x00
- };
- u16 vpfreq;
- u8 vu, p2, p1, p0;
- int i,ret;
- u16 tunestat;
-
- vp->fe_status = 0;
-
-// from at76c651.c it is a TUA6010XS
- vpfreq = (freq + 36125000) / 62500;
-
- dprintk("tuning to freq: %u (%2x,%2x), bw: %u, bufsize: %d",
- freq,(vpfreq >> 8) & 0xff, vpfreq & 0xff,bw,sizeof(bwbuf));
-
- if (freq > 400000000)
- vu = 1, p2 = 1, p1 = 0, p0 = 1;
- else if (freq > 140000000)
- vu = 0, p2 = 1, p1 = 1, p0 = 0;
- else
- vu = 0, p2 = 0, p1 = 1, p0 = 1;
-
- if ((ret = vp7041_03_cmd(vp,0x10,0x04,0x41,0x61,0x00)) ||
- (ret = vp7041_03_cmd(vp,0xc2,
- (vpfreq >> 8) & 0x7f,
- vpfreq & 0xff,
- 0x8e,
- (vu << 7) | (p2 << 2) | (p1 << 1) | p0 )) ||
- (ret = vp7041_03_cmd(vp,0x10,0x04,0x41,0x61,0x80)) )
- return ret;
-
- switch (bw) {
- case BANDWIDTH_6_MHZ:
- bwbuf[2] = 0x7e; bwbuf[4] = 0xbe; bwbuf[5] = 0xe9;
- bwbuf[11] = 0x21; bwbuf[13] = 0xd0; bwbuf[14] = 0x40;
- bwbuf[17] = 0x70; bwbuf[19] = 0xb6; bwbuf[20] = 0x2b;
- bwbuf[22] = 0x02; bwbuf[23] = 0x33; bwbuf[25] = 0x8e;
- bwbuf[26] = 0xd5;
- break;
- case BANDWIDTH_7_MHZ:
- bwbuf[2] = 0x93; bwbuf[4] = 0xde; bwbuf[5] = 0xbb;
- bwbuf[11] = 0x1c; bwbuf[13] = 0xfb; bwbuf[14] = 0xa5;
- bwbuf[17] = 0x60; bwbuf[19] = 0x9c; bwbuf[20] = 0x25;
- bwbuf[22] = 0x01; bwbuf[23] = 0xe3; bwbuf[25] = 0x0c;
- bwbuf[26] = 0xb7;
- break;
- case BANDWIDTH_8_MHZ:
- bwbuf[2] = 0xa8; bwbuf[4] = 0xfe; bwbuf[5] = 0x8c;
- bwbuf[11] = 0x19; bwbuf[13] = 0x5c; bwbuf[14] = 0x30;
- bwbuf[17] = 0x54; bwbuf[19] = 0x88; bwbuf[20] = 0xa0;
- bwbuf[22] = 0x01; bwbuf[23] = 0xa6; bwbuf[25] = 0xab;
- bwbuf[26] = 0x20;
- break;
- default:
- err("bandwidth: %d not supported",bw);
- return -ENOSYS;
- }
-
-
- for (i=0; i < sizeof(bwbuf); i+=3)
- if ((ret = vp7041_03_cmd(vp,0x10,0x00,bwbuf[i],bwbuf[i+1],bwbuf[i+2])))
- return ret;
-
- do {
- ret = vp7041_chk_tune (vp, 0xb2, &tunestat);
- } while (ret == 0 && !(tunestat & 0x01) && !(tunestat & 0x02));
-
- if ((ret = vp7041_chk_tune (vp, 0xab, &tunestat)))
- return ret;
-
- switch (tunestat) {
- case 0x01:
- for (i=0; i < sizeof(prefeedbuf); i += 2) {
- if ((ret = vp7041_02_cmd(vp,0x11,prefeedbuf[i],prefeedbuf[i+1],
- 0x00,0x02,&tunestat)))
- return ret;
- }
- vp->fe_status = FE_HAS_SIGNAL | FE_HAS_VITERBI | FE_HAS_SYNC |
- FE_HAS_CARRIER;
- break;
- case 0x00: // Tuning failed
- return 0;
- break;
- default:
- dprintk("Unknown tunestat (0x%x).\n",tunestat);
- break;
- }
-
- for (i=0; i < sizeof(prefeedbuf2); i+=3)
- if ((ret = vp7041_03_cmd(vp,0x10,0x00,prefeedbuf2[i],prefeedbuf2[i+1],
- prefeedbuf2[i+2])))
- return ret;
- vp->fe_status |= FE_HAS_LOCK;
- return ret;
-}
-
-#if 0
-/*
- * check the signal strength and quality
- * (TODO reverse engineer the result)
- */
-static int vp7041_signal_strength(struct usb_vp7041 *vp)
-{
- u8 b_out[] = {
- 0x48, 0xa7, 0xa8, 0x9e, 0x9f, 0xa4, 0x7c, 0x74, 0x75, 0x45
- };
- u16 vals[sizeof(b_out)];
- int i, ret;
-
- for (i=0; i < sizeof(b_out); i++)
- if ((ret = vp7041_chk_tune(vp,b_out[i],&vals[i])))
- return ret;
-
- return 0;
-}
-
-/* remote control (0x04) */
-/*
- * TODO: a tasklet should run with a delay of (1/10 second)
- * fill an appropriate event device ?
- */
-static int vp7041_rc_status(struct usb_vp7041 *vp)
-{
- u8 b_out[1] = { 0x04 },b_in[5];
- unsigned int actlen;
- int ret = 0;
-
- ret = vp7041_cmdmsg(vp,b_out,1,b_in,5,&actlen);
- if (!ret) {
- dprintk("remote control result: %x %x %x %x %x",
- b_in[0],b_in[1],b_in[2],b_in[3],b_in[4]);
- } else
- err("remote control cmd failed: %d",ret);
- return ret;
-}
-#endif
-static struct vp7041_channel *vp7041_channel_allocate(struct usb_vp7041 *vp)
-{
- int i;
- unsigned long flags;
- struct vp7041_channel *ch = NULL;
-
- spin_lock_irqsave(&vp->channel_lock,flags);
- for (i = 0; i < VP7041_MAX_PIDS; i++)
- if (!vp->channel[i].active) {
- ch = vp->channel + i;
- ch->active = 1;
- break;
- }
- spin_unlock_irqrestore(&vp->channel_lock,flags);
-
- return ch;
-}
-
-static int vp7041_set_channel(struct vp7041_channel *channel)
-{
- dprintk("set channel: feed_count: %d\n",channel->vp->feed_count);
- return vp7041_03_cmd(channel->vp,0x10, 0x00, channel->id,
- 0x20 + (channel->pid >> 8), channel->pid & 0xff);
-}
-
-static int vp7041_del_channel(struct vp7041_channel *channel)
-{
- // I think, spinlock at this point is not necessary, but maybe I'm wrong
- int ret;
- dprintk("del_channel: vp = %p, id = %x, active=%d, streamcount=%d pid=%x\n",
- channel->vp,channel->id,channel->active,channel->vp->feed_count,channel->pid);
- ret = vp7041_03_cmd(channel->vp,0x10, 0x00, channel->id, 0, 0);
- channel->active = 0;
- return ret;
-}
-
-static void vp7041_urb_complete(struct urb *urb, struct pt_regs *ptregs)
-{
- struct usb_vp7041 *vp = urb->context;
-
- if (!vp->streaming)
- return;
-
- if (urb->status == 0) {
- if (urb->actual_length % 188)
- dprintk("TS Packets: %d, %d\n", urb->actual_length/188,
- urb->actual_length % 188);
- dvb_dmx_swfilter_packets(&vp->demux, (u8*) urb->transfer_buffer,
- urb->actual_length/188);
- }
-
- if (vp->streaming)
- usb_submit_urb(urb,GFP_KERNEL);
-}
-
-static void vp7041_stop_xfer(struct usb_vp7041 *vp)
-{
- vp->streaming = 0;
- usb_unlink_urb(vp->buf_urb);
- if(!vp->disconnecting) {
- int i;
- for (i = 0; i < VP7041_MAX_PIDS; i++)
- vp7041_del_channel(&vp->channel[i]);
- vp->feed_count = 0;
-
- vp7041_03_cmd(vp,0x10, 0x00, 0x91, 0x00, 0x01);
- }
-}
-
-
-static int vp7041_start_xfer(struct usb_vp7041 *vp)
-{
- int ret;
-
- if (vp->streaming || vp->disconnecting)
- return 0;
-
- usb_fill_bulk_urb( vp->buf_urb, vp->udev, vp->data_pipe,
- vp->buffer, 8192, vp7041_urb_complete, vp);
- vp->buf_urb->transfer_flags = 0;
- vp->buf_urb->timeout = 0;
-
- // starting transfer in device
- if ((ret = vp7041_03_cmd(vp,0x10, 0x00, 0x91, 0x00, 0x00)))
- return ret;
-
- if ((ret = usb_submit_urb(vp->buf_urb,GFP_KERNEL))) {
- vp7041_stop_xfer(vp);
- err("could not submit buffer urb.");
- return ret;
- }
-
- vp->streaming = 1;
-
- return 0;
-}
-
-static int vp7041_start_feed(struct dvb_demux_feed *dvbdmxfeed)
-{
- struct dvb_demux *dvbdmx = dvbdmxfeed->demux;
- struct usb_vp7041 *vp = dvbdmxfeed->demux->priv;
- struct vp7041_channel *channel;
-
- dprintk("pid: 0x%04x, feedtype: %d\n", dvbdmxfeed->pid,
- dvbdmxfeed->type);
-
- if (!dvbdmx->dmx.frontend)
- return -EINVAL;
-
- if ((channel = vp7041_channel_allocate(vp)) == NULL)
- return -EBUSY;
-
- dvbdmxfeed->priv = channel;
- channel->pid = dvbdmxfeed->pid;
-
- vp7041_set_channel(channel);
-
- if (0 == vp->feed_count++)
- return vp7041_start_xfer(vp);
-
- return 0;
-}
-
-static int vp7041_stop_feed(struct dvb_demux_feed *dvbdmxfeed)
-{
- struct usb_vp7041 *vp = dvbdmxfeed->demux->priv;
- struct vp7041_channel *channel = (struct vp7041_channel *)
- dvbdmxfeed->priv;
-
- dprintk("stopfeed pid: 0x%04x, feedtype: %d",dvbdmxfeed->pid,
- dvbdmxfeed->type);
-
- if (channel == NULL)
- err("channel in dmxfeed->priv was NULL");
- else
- vp7041_del_channel(channel);
-
- if (--vp->feed_count == 0)
- vp7041_stop_xfer(vp);
-
- return 0;
-}
-
-static int vp7041_device_init (struct usb_vp7041 *vp)
-{
- int i,ret;
- u16 stat;
- u8 initbuf[] = {
- 0x03,0x00,0x03, 0x04,0x00,0x07,
-
- 0x06,0x00,0xb2, 0x07,0x23,0x1e, 0x08,0x00,0xa8, 0x09,0xfe,0x8c,
- 0x0a,0x00,0x00, 0x0b,0x00,0x02, 0x0c,0x00,0x0a, 0x0f,0x01,0xff,
-
- 0x24,0x03,0x99,
-
- 0x13,0x00,0x01, 0x14,0xcc,0xcd, 0x15,0x02,0x6f, 0x16,0x00,0x80,
- 0x17,0x00,0xa6, 0x18,0x00,0xc3, 0x19,0x00,0x3d, 0x1a,0x00,0x01,
- 0x1b,0xd2,0x06, 0x1c,0x94,0x7b, 0x1d,0x00,0x00, 0x1e,0x00,0x5a,
- 0x1f,0x00,0x21, 0x20,0x00,0x17,
-
- 0x57,0x00,0x00,
-
- 0x21,0x00,0x02, 0x22,0x02,0x20, 0x23,0x00,0x00, 0x25,0x00,0x05,
- 0x26,0x00,0x04, 0x27,0x00,0x87, 0x28,0x00,0x87,
-
- 0x2b,0x08,0x28, 0x2c,0x00,0x0a, 0x2d,0x08,0x28, 0x2e,0x00,0x0a,
- 0x2f,0x0d,0x78, 0x30,0x00,0x05, 0x31,0x0d,0x78, 0x32,0x00,0x05,
- 0x33,0x00,0x04, 0x34,0x00,0x04, 0x35,0x00,0x80, 0x36,0x00,0x0b,
- 0x37,0x00,0x00, 0x38,0x00,0x19, 0x39,0x5c,0x30, 0x3a,0x00,0x54,
- 0x3b,0x88,0xa0, 0x3c,0x01,0xa6, 0x3d,0xab,0x20, 0x3e,0x00,0x00,
- 0x3f,0x03,0xe8, 0x40,0x00,0x00, 0x41,0x03,0xf2, 0x42,0x00,0x01,
- 0x43,0xb0,0xd0, 0x44,0x00,0x00, 0x45,0x00,0x00, 0x47,0x00,0x00,
- 0x4d,0x00,0x06, 0x4e,0x00,0x80, 0x4f,0x00,0x01,
-
- 0x5c,0x00,0x80,
-
- 0x60,0x00,0x10, 0x61,0x00,0x09, 0x6a,0x00,0x80, 0x6b,0x00,0x80,
- 0x6c,0x00,0x80,
-
- 0x7a,0x0b,0x33, 0x7e,0x00,0x00,
-
- 0x81,0x00,0x00, 0x82,0x00,0x01,
-
- 0x87,0x00,0x01, 0x8f,0x00,0x00,
-
- 0xab,0x00,0xe2, 0xac,0x00,0xa0, 0xad,0x00,0x1d, 0xae,0x03,0xd3,
- 0xaf,0x03,0xe6, 0xb0,0x00,0x13, 0xb1,0x00,0x16, 0xb2,0x03,0xfb,
- 0xb3,0x03,0xee, 0xb4,0x03,0xfe, 0xb5,0x00,0x0c, 0xb6,0x00,0x06,
- 0xb7,0x03,0xf9, 0xb8,0x03,0xf9, 0xb9,0x00,0x03, 0xba,0x00,0x06,
- 0xbc,0x03,0xfb, 0xbd,0x03,0xfd, 0xbe,0x00,0x02, 0xbf,0x00,0x03,
- 0xc0,0x00,0x01,
-
- 0xc2,0x00,0x00, 0xc3,0x00,0x01,
-
- 0xce,0x7f,0xff, 0xcf,0x0f,0xff,
-
- 0xa9,0x00,0x06,
-
- 0x8e,0x00,0x00, 0x8f,0x00,0x01, 0x90,0x00,0x01, 0x91,0x00,0x01,
- 0x92,0x00,0x03, 0x93,0x01,0x00,
-
- 0x99,0x00,0x00, 0x99,0x00,0x00, 0x99,0x00,0x00, 0x99,0x00,0x00,
- 0x99,0x00,0x00, 0x99,0x00,0x00, 0x99,0x00,0x00, 0x99,0x00,0x00,
- 0x99,0x00,0x00, 0x99,0x00,0x00, 0x99,0x00,0x00, 0x99,0x00,0x00,
- 0x99,0x00,0x00, 0x99,0x00,0x00, 0x99,0x00,0x00, 0x99,0x00,0x00,
-
- 0x7f,0x00,0x00
- };
- if ((ret = vp7041_sndmsg(vp,vp7041_init_buf,sizeof(vp7041_init_buf))))
- return ret;
-
- if ((ret = vp7041_03_cmd(vp,0x10,0x04,0x04,0x00,0x00))) return ret;
- if ((ret = vp7041_02_cmd(vp,0x11,0x84,0x01,0x00,0x02,&stat))) return ret;
- if (stat != 0x01b3) {
- dprintk("unexpected known value returned during initialization (%.4x)",stat);
- return -ENOSYS;
- }
- if ((ret = vp7041_03_cmd(vp,0x10,0x00,0x00,0x00,0x04))) return ret;
- if ((ret = vp7041_03_cmd(vp,0x10,0x04,0x00,0x81,0x2c))) return ret;
- if ((ret = vp7041_03_cmd(vp,0x10,0x04,0x00,0x00,0x04))) return ret;
- if ((ret = vp7041_03_cmd(vp,0x10,0x04,0x03,0x90,0x00))) return ret;
- if ((ret = vp7041_03_cmd(vp,0x10,0x04,0x05,0x00,0x01))) return ret;
-
- for (i = 0; i < sizeof(initbuf); i+=3)
- if ((ret = vp7041_03_cmd(vp,0x10,0x00,initbuf[i],
- initbuf[i+1],initbuf[i+2])))
- return ret;
-
- return 0;
-}
-
-static int vp7041_dvb_init(struct usb_vp7041 *vp)
-{
- int ret;
-
-#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,4)
- if ((ret = dvb_register_adapter(&vp->adapter, DRIVER_DESC)) < 0) {
-#else
- if ((ret = dvb_register_adapter(&vp->adapter, DRIVER_DESC ,
- THIS_MODULE)) < 0) {
-#endif
- dprintk("dvb_register_adapter failed: error %d", ret);
- goto err;
- }
- vp->demux.dmx.capabilities = DMX_TS_FILTERING | DMX_SECTION_FILTERING;
-
- vp->demux.priv = (void *)vp;
- vp->demux.filternum = 15;
- vp->demux.feednum = 15;
- vp->demux.start_feed = vp7041_start_feed;
- vp->demux.stop_feed = vp7041_stop_feed;
- vp->demux.write_to_decoder = NULL;
- if ((ret = dvb_dmx_init(&vp->demux)) < 0) {
- err("dvb_dmx_init failed: error %d",ret);
- goto err_dmx;
- }
-
- vp->dmxdev.filternum = vp->demux.filternum;
- vp->dmxdev.demux = &vp->demux.dmx;
- vp->dmxdev.capabilities = 0;
- if ((ret = dvb_dmxdev_init(&vp->dmxdev, vp->adapter)) < 0) {
- err("dvb_dmxdev_init failed: error %d",ret);
- goto err_dmx_dev;
- }
-
- vp->frontend.source = DMX_FRONTEND_0;
- if ((ret = vp->demux.dmx.add_frontend(&vp->demux.dmx,
- &vp->frontend)) < 0) {
- err("dmx_add_frontend failed: error %d", ret);
- goto err_add_fe;
- }
-
- if ((ret = vp->demux.dmx.connect_frontend(&vp->demux.dmx,
- &vp->frontend)) < 0) {
- err("dmx_connect_frontend failed: error %d\n",ret);
- goto err_conn_fe;
- }
-
- vp->fe_status = 0;
-
- dvb_net_init(vp->adapter, &vp->dvb_net, &vp->demux.dmx);
-
- goto success;
-err_conn_fe:
- vp->demux.dmx.remove_frontend(&vp->demux.dmx, &vp->frontend);
-err_add_fe:
- dvb_dmxdev_release(&vp->dmxdev);
-err_dmx_dev:
- dvb_dmx_release(&vp->demux);
-err_dmx:
- dvb_unregister_adapter(vp->adapter);
-err:
- return ret;
-success:
- return 0;
-}
-
-static int vp7041_dvb_exit(struct usb_vp7041 *vp)
-{
- info("unregistering DVB part");
- dvb_net_release(&vp->dvb_net);
- vp->demux.dmx.close(&vp->demux.dmx);
- vp->demux.dmx.remove_frontend(&vp->demux.dmx, &vp->frontend);
- dvb_dmxdev_release(&vp->dmxdev);
- dvb_dmx_release(&vp->demux);
- dvb_unregister_adapter(vp->adapter);
-
- return 0;
-}
-
-static int vp7041_ioctl(struct dvb_frontend *fe, unsigned int cmd, void *arg)
-{
- struct usb_vp7041 *vp = fe->data;
-
- switch (cmd) {
- case FE_GET_INFO:
- dprintk("FE_GET_INFO\n");
- memcpy(arg, &vp7041_frontend_info,
- sizeof (struct dvb_frontend_info));
- break;
- case FE_READ_STATUS: {
- fe_status_t *status = (fe_status_t *)arg;
- dprintk("FE_READ_STATUS\n");
- *status = vp->fe_status;
- }
- break;
- case FE_READ_BER:
- dprintk("FE_READ_BER\n");
- return -EINVAL;
- break;
- case FE_READ_SIGNAL_STRENGTH: {
-// TODO vp7041_signal_strength(vp);
- u16 *val = (u16*) arg;
- *val = 0xFFFF;
- break;
- }
- case FE_READ_SNR: {
- u16 *val = (u16*) arg;
- *val = 0xFFFF;
-// TODO vp7041_signal_strength
- dprintk("FE_READ_SNR\n");
- break;
- }
- case FE_READ_UNCORRECTED_BLOCKS:
- dprintk("FE_READ_UNCORRECTED_BLOCKS\n");
- return -EINVAL;
- break;
- case FE_SET_FRONTEND: {
- struct dvb_frontend_parameters *p =
- (struct dvb_frontend_parameters *) arg;
- vp->fe_params = *p;
- dprintk("FE_SET_FRONTEND, freq: %d rate: %d bw:%d inv: %d\n",
- p->frequency,p->u.qam.symbol_rate,p->u.ofdm.bandwidth,p->inversion);
- return vp7041_tune(vp,p->frequency,p->u.ofdm.bandwidth);
- break;
- }
- case FE_GET_FRONTEND: {
- struct dvb_frontend_parameters *p =
- (struct dvb_frontend_parameters *) arg;
- dprintk("FE_GET_FRONTEND\n");
- *p = vp->fe_params;
- }
- break;
- case FE_SLEEP:
- dprintk("FE_SLEEP\n");
- return -ENOSYS;
- break;
- case FE_INIT:
- dprintk("FE_INIT\n");
- return -EINVAL;
- break;
- default:
- return -EINVAL;
- }
- return 0;
-}
-
-static int vp7041_frontend_init(struct usb_vp7041 *vp)
-{
- int ret;
-
- ret = dvb_register_frontend(vp7041_ioctl, vp->adapter, vp, &vp7041_frontend_info, THIS_MODULE);
- if (ret)
- return ret;
- return 0;
-}
-
-static void vp7041_frontend_exit(struct usb_vp7041 *vp)
-{
- dvb_unregister_frontend(vp7041_ioctl, vp->adapter);
-}
-
-static int vp7041_exit (struct usb_vp7041 *vp)
-{
- usb_free_urb(vp->buf_urb);
- pci_free_consistent(NULL,8192,vp->buffer,vp->dma_handle);
- return 0;
-}
-
-static int vp7041_init(struct usb_vp7041 *vp)
-{
- int ret,i;
- unsigned long flags;
-
- sema_init(&vp->usb_sem, 1);
- spin_lock_init(&vp->channel_lock);
-
- vp->command_pipe = usb_sndbulkpipe(vp->udev, COMMAND_PIPE);
- vp->result_pipe = usb_rcvbulkpipe(vp->udev, RESULT_PIPE);
- vp->data_pipe = usb_rcvbulkpipe(vp->udev, DATA_PIPE);
-
- // when reloading the driver w/o replugging the device
- // a timeout occures, this should help
- usb_clear_halt(vp->udev,vp->command_pipe);
- usb_clear_halt(vp->udev,vp->result_pipe);
- usb_clear_halt(vp->udev,vp->data_pipe);
-
- vp->buffer = pci_alloc_consistent(NULL,8192, &vp->dma_handle);
- memset(vp->buffer,0,8192);
- if (!(vp->buf_urb = usb_alloc_urb(0,GFP_KERNEL))) {
- pci_free_consistent(NULL,8192,vp->buffer,vp->dma_handle);
- return -ENOMEM;
- }
- spin_lock_irqsave(&vp->channel_lock,flags);
- for (i=0; i < VP7041_MAX_PIDS; i++) {
- vp->channel[i].vp = vp;
- vp->channel[i].id = 0x99+i;
- vp->channel[i].active = 0;
- }
- spin_unlock_irqrestore(&vp->channel_lock,flags);
-
- ret = vp7041_device_init(vp);
- if (ret) {
- vp7041_exit(vp);
- return ret;
- }
-
- ret = vp7041_dvb_init(vp);
- if (ret) {
- vp7041_exit(vp);
- return ret;
- }
-
- ret = vp7041_frontend_init(vp);
- if (ret) {
- vp7041_dvb_exit(vp);
- vp7041_exit(vp);
- return ret;
- }
-
- return 0;
-}
-
-static int vp7041_loadfirmware(struct usb_device *udev)
-{
- const struct firmware *fw = NULL;
- int ret = 0, i;
- for (i = 0; i < sizeof(firmware_filenames)/sizeof(char*); i++) {
- if ((ret = request_firmware(&fw, firmware_filenames[i], &udev->dev)) == 0) {
- info("found firmware file (%s).",firmware_filenames[i]);
- break;
- }
- dprintk("Firmware '%s' not found. (%d)\n",firmware_filenames[i],ret);
- }
-
-
- if (fw == NULL) {
- err("Did not find a valid firmware.");
- return -EINVAL;
- }
-
- if (!(fw->size % 22)) {
- int i;
- u16 addr;
- u8 *b,*p = kmalloc(fw->size,GFP_KERNEL);
- if (p != NULL) {
- /*
- * you cannot use the fw->data as buffer for
- * usb_control_msg, a new buffer has to be
- * created
- */
- memcpy(p,fw->data,fw->size);
- for(i = 0; i < fw->size; i += 22) {
- b = (u8 *) &p[i];
- addr = *((u16 *) &b[3]);
-
- ret = usb_control_msg(udev, usb_sndctrlpipe(udev,0),
- 0xa0, USB_TYPE_VENDOR, addr, 0x00, &b[6],
- (u16) b[1], 5*HZ);
-
- if (ret != b[1]) {
- err("error while transferring firmware "
- "(transferred size: %d, block size: %d)",
- ret,b[1]);
- ret = -EINVAL;
- break;
- }
- }
- kfree(p);
- ret = 0;
- } else
- ret = -ENOMEM;
- } else {
- err("invalid firmware filesize.");
- ret = -ENODEV;
- }
- release_firmware(fw);
-
- return ret;
-}
-
-
-static int vp7041_probe(struct usb_interface *intf,
- const struct usb_device_id *id)
-{
- struct usb_device *udev = interface_to_usbdev(intf);
- struct usb_vp7041 *vp = NULL;
-
- int retval = -ENOMEM;
-
- switch (udev->descriptor.idProduct) {
- case USB_VP7041_PRODUCT_PREFW_ID:
- retval = vp7041_loadfirmware(udev);
- break;
- case USB_VP7041_PRODUCT_ID:
- vp = kmalloc(sizeof(struct usb_vp7041),GFP_KERNEL);
- if (vp == NULL) {
- err("no memory");
- return retval;
- }
- memset(vp,0,sizeof(struct usb_vp7041));
- vp->udev = udev;
- usb_set_intfdata(intf, vp);
-
- retval = vp7041_init(vp);
-
- break;
- default:
- err("something went very wrong, "
- "unknown product ID: %.4x",udev->descriptor.idProduct);
- retval = -ENODEV;
- break;
- }
- if (retval == 0)
- info( DRIVER_DESC " successfully initialized and connected.");
- else
- info( DRIVER_DESC " error while loading driver (%d)",retval);
- return retval;
-}
-
-static void vp7041_disconnect(struct usb_interface *intf)
-{
- struct usb_vp7041 *vp = usb_get_intfdata(intf);
- usb_set_intfdata(intf,NULL);
-
- if (vp != NULL) {
- vp->disconnecting = 1;
- vp7041_stop_xfer(vp);
- vp7041_frontend_exit(vp);
- vp7041_dvb_exit(vp);
- vp7041_exit(vp);
- kfree(vp);
- }
-
- info( DRIVER_DESC " successfully deinitialized and disconnected.");
-}
-
-/* usb specific object needed to register this driver with the usb subsystem */
-static struct usb_driver vp7041_driver = {
- .owner = THIS_MODULE,
- .name = "vp7041",
- .probe = vp7041_probe,
- .disconnect = vp7041_disconnect,
- .id_table = vp7041_table,
-};
-
-/* module stuff */
-static int __init usb_vp7041_init(void)
-{
- int result;
-
- if ((result = usb_register(&vp7041_driver))) {
- err("usb_register failed. Error number %d",result);
- return result;
- }
-
- return 0;
-}
-
-static void __exit usb_vp7041_exit(void)
-{
- /* deregister this driver from the USB subsystem */
- usb_deregister(&vp7041_driver);
-}
-
-module_init (usb_vp7041_init);
-module_exit (usb_vp7041_exit);
-
-MODULE_AUTHOR(DRIVER_AUTHOR);
-MODULE_DESCRIPTION(DRIVER_DESC);
-MODULE_LICENSE("GPL");