summaryrefslogtreecommitdiff
path: root/linux
diff options
context:
space:
mode:
authorPatrick Boettcher <devnull@localhost>2004-11-05 09:16:55 +0000
committerPatrick Boettcher <devnull@localhost>2004-11-05 09:16:55 +0000
commit801d2fbdd1c4ff28e9e6922dbfa6697b1b57e822 (patch)
treecdd367db4ddd3ae6638c0a46e817edc17c619332 /linux
parent2592322f1bc06dc56609ea4ac281357f37c38e9e (diff)
downloadmediapointer-dvb-s2-801d2fbdd1c4ff28e9e6922dbfa6697b1b57e822.tar.gz
mediapointer-dvb-s2-801d2fbdd1c4ff28e9e6922dbfa6697b1b57e822.tar.bz2
- enable several new devices (even the broken Artec T1 with a Kconfig switch)
- fixed dvb-dibusb in order to get along with dib3000 changes
Diffstat (limited to 'linux')
-rw-r--r--linux/drivers/media/dvb/dibusb/Kconfig28
-rw-r--r--linux/drivers/media/dvb/dibusb/dvb-dibusb.c331
-rw-r--r--linux/drivers/media/dvb/dibusb/dvb-dibusb.h326
3 files changed, 388 insertions, 297 deletions
diff --git a/linux/drivers/media/dvb/dibusb/Kconfig b/linux/drivers/media/dvb/dibusb/Kconfig
index afe683681..c37fb4bac 100644
--- a/linux/drivers/media/dvb/dibusb/Kconfig
+++ b/linux/drivers/media/dvb/dibusb/Kconfig
@@ -1,34 +1,44 @@
config DVB_DIBUSB
- tristate "DiBcom/Twinhan/KWorld/Hama/Artec/Compro USB DVB-T devices"
+ tristate "DiBcom USB DVB-T devices (see help for device list)"
depends on DVB_CORE && USB
select FW_LOADER
select DVB_DIB3000MB
+ select DVB_DIB3000MC
help
- Support for USB 1.1 DVB-T devices based on a reference design made by
+ Support for USB 1.1 and 2.0 DVB-T devices based on reference designs made by
DiBcom (http://www.dibcom.fr).
Devices supported by this driver:
TwinhanDTV USB-Ter (VP7041)
- TwinhanDTV Magic Box (VP7041e)
+ TwinhanDTV Magic Box (VP7041e)
KWorld V-Stream XPERT DTV - DVB-T USB
Hama DVB-T USB-Box
DiBcom reference device (non-public)
Ultima Electronic/Artec T1 USB TVBOX
Compro Videomate DVB-U2000 - DVB-T USB
+ Grandtec DVB-T USB
+ Avermedia AverTV DVBT USB
+ Yakumo DVB-T mobile USB2.0
The VP7041 seems to be identical to "CTS Portable" (Chinese
Television System).
These devices can be understood as budget ones, they "only" deliver
- the MPEG data.
+ (a part of) the MPEG2 transport stream.
- Currently all known copies of the DiBcom reference design have the DiBcom 3000-MB
- frontend onboard. Please enable and load this one manually in order to use this
- device.
-
- A firmware is needed to use the device. See Documentation/dvb/README.dibusb
+ A firmware is needed to get the device working. See Documentation/dvb/README.dibusb
details.
Say Y if you own such a device and want to use it. You should build it as
a module.
+
+config DVB_DIBUSB_MISDESIGNED_AN2235
+ bool "Enable support for some Artec T1 device, which identifies as AN2235"
+ depends on DVB_DIBUSB
+ help
+ Somehow Artec forgot to program the eeprom for some of their T1 devices. So
+ comes that they identify with the default Vendor and Product ID of the Cypress
+ CY7C64613 (AN2235).
+
+ Say Y if your Artec device has 0x0574 as Vendor ID and 0x2235 as Product ID.
diff --git a/linux/drivers/media/dvb/dibusb/dvb-dibusb.c b/linux/drivers/media/dvb/dibusb/dvb-dibusb.c
index 32d52b2c9..65fbd3940 100644
--- a/linux/drivers/media/dvb/dibusb/dvb-dibusb.c
+++ b/linux/drivers/media/dvb/dibusb/dvb-dibusb.c
@@ -18,7 +18,7 @@
* Acknowledgements
*
* Amaury Demol (ademol@dibcom.fr) from DiBcom for providing specs and driver
- * sources, on which this driver (and the dib3000mb frontend) are based.
+ * sources, on which this driver (and the dib3000mb/mc/p frontends) are based.
*
* see Documentation/dvb/README.dibusb for more information
*/
@@ -36,7 +36,7 @@
#include "dvb_filter.h"
#include "dvb_net.h"
#include "dvb_frontend.h"
-#include "dib3000mb.h"
+#include "dib3000.h"
#include "dvb-dibusb.h"
@@ -44,7 +44,7 @@
/* debug */
#ifdef CONFIG_DVB_DIBCOM_DEBUG
-#define dprintk_new(level,args...) \
+#define dprintk(level,args...) \
do { if ((debug & level)) { printk(args); } } while (0)
#define debug_dump(b,l) if (debug) {\
@@ -57,18 +57,18 @@ static int debug;
module_param(debug, int, 0x644);
MODULE_PARM_DESC(debug, "set debugging level (1=info,2=xfer,4=alotmore,8=ts,16=err (|-able)).");
#else
-#define dprintk_new(args...)
+#define dprintk(args...)
#define debug_dump(b,l)
#endif
-#define deb_info(args...) dprintk_new(0x01,args)
-#define deb_xfer(args...) dprintk_new(0x02,args)
-#define deb_alot(args...) dprintk_new(0x04,args)
-#define deb_ts(args...) dprintk_new(0x08,args)
-#define deb_err(args...) dprintk_new(0x10,args)
+#define deb_info(args...) dprintk(0x01,args)
+#define deb_xfer(args...) dprintk(0x02,args)
+#define deb_alot(args...) dprintk(0x04,args)
+#define deb_ts(args...) dprintk(0x08,args)
+#define deb_err(args...) dprintk(0x10,args)
/* Version information */
-#define DRIVER_VERSION "0.0"
+#define DRIVER_VERSION "0.1"
#define DRIVER_DESC "Driver for DiBcom based USB Budget DVB-T device"
#define DRIVER_AUTHOR "Patrick Boettcher, patrick.boettcher@desy.de"
@@ -83,25 +83,28 @@ static int dibusb_readwrite_usb(struct usb_dibusb *dib,
if ((ret = down_interruptible(&dib->usb_sem)))
return ret;
- if (dib->streaming && wbuf[0] == DIBUSB_REQ_I2C_WRITE)
- deb_err("BUG: writing to i2c, while TS-streaming destroys the stream. What"
- " did you do ? Please enable debugging and send the syslog to the author. (%x reg: %x %x)",
- wbuf[0],wbuf[2],wbuf[3]);
+ if (dib->feedcount &&
+ wbuf[0] == DIBUSB_REQ_I2C_WRITE &&
+ dib->dibdev->parm->type == DIBUSB1_1)
+ deb_err("BUG: writing to i2c, while TS-streaming destroys the stream."
+ "(%x reg: %x %x)", wbuf[0],wbuf[2],wbuf[3]);
debug_dump(wbuf,wlen);
-
- ret = usb_bulk_msg(dib->udev,COMMAND_PIPE,
- wbuf,wlen,&actlen,DIBUSB_I2C_TIMEOUT);
+
+ ret = usb_bulk_msg(dib->udev,usb_sndbulkpipe(dib->udev,
+ dib->dibdev->parm->cmd_pipe), wbuf,wlen,&actlen,
+ DIBUSB_I2C_TIMEOUT);
if (ret)
err("bulk message failed: %d (%d/%d)",ret,wlen,actlen);
else
ret = actlen != wlen ? -1 : 0;
- /* an answer is expected */
+ /* an answer is expected, and no error before */
if (!ret && rbuf && rlen) {
- ret = usb_bulk_msg(dib->udev,RESULT_PIPE,rbuf,rlen,
- &actlen,DIBUSB_I2C_TIMEOUT);
+ ret = usb_bulk_msg(dib->udev,usb_rcvbulkpipe(dib->udev,
+ dib->dibdev->parm->result_pipe),rbuf,rlen,&actlen,
+ DIBUSB_I2C_TIMEOUT);
if (ret)
err("recv bulk message failed: %d",ret);
@@ -141,82 +144,6 @@ static int dibusb_i2c_msg(struct usb_dibusb *dib, u8 addr,
/*
* DVB stuff
*/
-
-static struct dibusb_pid * dibusb_get_free_pid(struct usb_dibusb *dib)
-{
- int i;
- unsigned long flags;
- struct dibusb_pid *dpid = NULL;
-
- spin_lock_irqsave(&dib->pid_list_lock,flags);
- for (i=0; i < DIBUSB_MAX_PIDS; i++)
- if (!dib->pid_list[i].active) {
- dpid = dib->pid_list + i;
- dpid->active = 1;
- break;
- }
- spin_unlock_irqrestore(&dib->pid_list_lock,flags);
- return dpid;
-}
-
-static int dibusb_start_xfer(struct usb_dibusb *dib)
-{
- u8 b[4] = {
- (DIB3000MB_REG_FIFO >> 8) & 0xff,
- (DIB3000MB_REG_FIFO) & 0xff,
- (DIB3000MB_FIFO_ACTIVATE >> 8) & 0xff,
- (DIB3000MB_FIFO_ACTIVATE) & 0xff
- };
- dib->streaming = 1;
- deb_ts("start streaming\n");
- return dibusb_i2c_msg(dib,DIBUSB_DEMOD_I2C_ADDR_DEFAULT,b,4,NULL,0);
-}
-
-static int dibusb_stop_xfer(struct usb_dibusb *dib)
-{
- u8 b[4] = {
- (DIB3000MB_REG_FIFO >> 8) & 0xff,
- (DIB3000MB_REG_FIFO) & 0xff,
- (DIB3000MB_FIFO_INHIBIT >> 8) & 0xff,
- (DIB3000MB_FIFO_INHIBIT) & 0xff
- };
- dib->streaming = 0;
- deb_ts("stop streaming\n");
- return dibusb_i2c_msg(dib,DIBUSB_DEMOD_I2C_ADDR_DEFAULT,b,4,NULL,0);
-}
-
-static int dibusb_set_pid(struct dibusb_pid *dpid)
-{
- struct usb_dibusb *dib = dpid->dib;
- u16 pid = dpid->pid | (dpid->active ? DIB3000MB_ACTIVATE_FILTERING : 0);
- u8 b[4] = {
- (dpid->reg >> 8) & 0xff,
- (dpid->reg) & 0xff,
- (pid >> 8) & 0xff,
- (pid) & 0xff
- };
- int ret;
-
- /* firmware bug, i2c write during mpeg transfer */
- if (dib->feedcount) {
- deb_info("stop streaming\n");
- ret = dibusb_stop_xfer(dib);
- }
-
- if (dpid->active)
- dib->feedcount++;
- else
- dib->feedcount--;
-
- ret = dibusb_i2c_msg(dib,DIBUSB_DEMOD_I2C_ADDR_DEFAULT,b,4,NULL,0);
-
- if (ret == 0 && dib->feedcount) {
- deb_info("start streaming\n");
- ret = dibusb_start_xfer(dib);
- }
- return ret;
-}
-
static void dibusb_urb_complete(struct urb *urb, struct pt_regs *ptregs)
{
struct usb_dibusb *dib = urb->context;
@@ -231,7 +158,7 @@ static void dibusb_urb_complete(struct urb *urb, struct pt_regs *ptregs)
/* Francois recommends to drop not full-filled packets, even if they may
* contain valid TS packets
*/
- if (urb->actual_length == DIBUSB_TS_DEFAULT_SIZE && dib->dvb_is_ready)
+ if (urb->actual_length == dib->dibdev->parm->default_size && dib->dvb_is_ready)
dvb_dmx_swfilter_packets(&dib->demux, (u8*) urb->transfer_buffer,urb->actual_length/188);
else
deb_ts("URB dropped because of the "
@@ -242,46 +169,73 @@ static void dibusb_urb_complete(struct urb *urb, struct pt_regs *ptregs)
usb_submit_urb(urb,GFP_KERNEL);
}
-
-static int dibusb_start_feed(struct dvb_demux_feed *dvbdmxfeed)
+static int dibusb_ctrl_feed(struct usb_dibusb *dib, int pid, int onoff)
{
-// struct dvb_demux *dvbdmx = dvbdmxfeed->demux;
- struct usb_dibusb *dib = dvbdmxfeed->demux->priv;
- struct dibusb_pid *dpid;
-
- deb_ts("pid: 0x%04x, feedtype: %d\n", dvbdmxfeed->pid,dvbdmxfeed->type);
+ if (dib->dibdev->parm->firmware_bug && dib->feedcount) {
+ deb_ts("stop feeding\n");
+ if (dib->xfer_ops.fifo_ctrl != NULL) {
+ if (dib->xfer_ops.fifo_ctrl(dib->fe,0)) {
+ err("error while inhibiting fifo.");
+ return -ENODEV;
+ }
+ } else {
+ err("fifo_ctrl is not set.");
+ return -ENODEV;
+ }
+ }
+
+ dib->feedcount += onoff ? 1 : -1;
- if ((dpid = dibusb_get_free_pid(dib)) == NULL) {
- err("no free pid in list.");
+ if (dib->xfer_ops.pid_ctrl != NULL) {
+ if (dib->xfer_ops.pid_ctrl(dib->fe,pid,onoff) < 0) {
+ err("no free pid in list.");
+ return -ENODEV;
+ }
+ } else {
+ err("no pid ctrl callback.");
return -ENODEV;
}
- dvbdmxfeed->priv = dpid;
- dpid->pid = dvbdmxfeed->pid;
-
- dibusb_set_pid(dpid);
-
+ /*
+ * start the feed, either if there is the firmware bug or
+ * if this was the first pid to set.
+ */
+ if (dib->dibdev->parm->firmware_bug || dib->feedcount == onoff) {
+ deb_ts("start feeding\n");
+ if (dib->xfer_ops.fifo_ctrl != NULL) {
+ if (dib->xfer_ops.fifo_ctrl(dib->fe,1)) {
+ err("error while enabling fifo.");
+ return -ENODEV;
+ }
+ } else {
+ err("fifo_ctrl is not set.");
+ return -ENODEV;
+ }
+ }
return 0;
}
-static int dibusb_stop_feed(struct dvb_demux_feed *dvbdmxfeed)
+static int dibusb_start_feed(struct dvb_demux_feed *dvbdmxfeed)
{
- struct dibusb_pid *dpid = (struct dibusb_pid *) dvbdmxfeed->priv;
+ struct usb_dibusb *dib = dvbdmxfeed->demux->priv;
+ deb_ts("pid: 0x%04x, feedtype: %d\n", dvbdmxfeed->pid,dvbdmxfeed->type);
+ dvbdmxfeed->priv = dib;
+ return dibusb_ctrl_feed(dib,dvbdmxfeed->pid,1);
+}
- deb_ts("stopfeed pid: 0x%04x, feedtype: %d\n",dvbdmxfeed->pid, dvbdmxfeed->type);
-
- if (dpid == NULL)
- err("channel in dmxfeed->priv was NULL");
- else {
- dpid->active = 0;
- dpid->pid = 0;
- dibusb_set_pid(dpid);
+static int dibusb_stop_feed(struct dvb_demux_feed *dvbdmxfeed)
+{
+ struct usb_dibusb *dib = (struct usb_dibusb *) dvbdmxfeed->priv;
+ if (dib == NULL) {
+ err("dib in dmxfeed->priv was NULL");
+ return -EINVAL;
}
-
- return 0;
+ deb_ts("dvbdmxfeed pid: 0x%04x, feedtype: %d\n",
+ dvbdmxfeed->pid, dvbdmxfeed->type);
+ return dibusb_ctrl_feed(dib,dvbdmxfeed->pid,0);
}
/*
- * Cypress transfers
+ * Cypress controls
*/
#if 0
@@ -318,8 +272,6 @@ static int dibusb_read_remote_control(struct usb_dibusb *dib)
if ((ret = dibusb_readwrite_usb(dib,b,1,rb,5)))
return ret;
-
-
switch (rb[0]) {
case DIBUSB_RC_NEC_KEY_PRESSED:
@@ -398,7 +350,7 @@ static u32 dibusb_i2c_func(struct i2c_adapter *adapter)
static int thomson_cable_eu_pll_set(struct dvb_frontend* fe, struct dvb_frontend_parameters* params);
-static struct dib3000mb_config thomson_cable_eu_config = {
+static struct dib3000_config thomson_cable_eu_config = {
.demod_address = 0x10,
.pll_addr = 194,
.pll_set = thomson_cable_eu_pll_set,
@@ -446,7 +398,7 @@ static struct i2c_algorithm dibusb_algo = {
static void frontend_init(struct usb_dibusb* dib)
{
- dib->fe = dib3000mb_attach(&thomson_cable_eu_config, &dib->i2c_adap);
+ dib->fe = dib3000mb_attach(&thomson_cable_eu_config, &dib->i2c_adap,&dib->xfer_ops);
if (dib->fe == NULL) {
printk("dvb-dibusb: A frontend driver was not found for device %04x/%04x\n",
@@ -462,7 +414,6 @@ static void frontend_init(struct usb_dibusb* dib)
}
}
-
static int dibusb_dvb_init(struct usb_dibusb *dib)
{
int ret;
@@ -498,8 +449,8 @@ static int dibusb_dvb_init(struct usb_dibusb *dib)
dib->demux.dmx.capabilities = DMX_TS_FILTERING | DMX_SECTION_FILTERING;
dib->demux.priv = (void *)dib;
- dib->demux.filternum = DIBUSB_MAX_PIDS;
- dib->demux.feednum = DIBUSB_MAX_PIDS;
+ /* get pidcount from demod */
+ dib->demux.feednum = dib->demux.filternum = 16;
dib->demux.start_feed = dibusb_start_feed;
dib->demux.stop_feed = dibusb_stop_feed;
dib->demux.write_to_decoder = NULL;
@@ -552,21 +503,36 @@ static int dibusb_dvb_exit(struct usb_dibusb *dib)
static int dibusb_exit(struct usb_dibusb *dib)
{
int i;
- for (i = 0; i < DIBUSB_TS_NUM_URBS; i++)
- if (dib->buf_urb[i] != NULL) {
- deb_info("killing URB no. %d.\n",i);
- usb_kill_urb(dib->buf_urb[i]); // TODO kernel version ifdef for unlink_urb
-
- deb_info("freeing URB no. %d.\n",i);
- usb_free_urb(dib->buf_urb[i]);
+ if (dib->urb_list != NULL) {
+ for (i = 0; i < dib->dibdev->parm->num_urbs; i++) {
+ if (dib->urb_list[i] != NULL) {
+ deb_info("killing URB no. %d.\n",i);
+
+ /* stop the URBs */
+#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,7)
+ usb_unlink_urb(dib->urb_list[i]);
+#else
+ usb_kill_urb(dib->urb_list[i]);
+#endif
+
+ deb_info("freeing URB no. %d.\n",i);
+ /* free the URBs */
+ usb_free_urb(dib->urb_list[i]);
+ }
}
- pci_free_consistent(NULL,DIBUSB_TS_BUFFER_SIZE,dib->buffer,dib->dma_handle);
+ /* free the urb array */
+ kfree(dib->urb_list);
+ }
+
+ pci_free_consistent(NULL,
+ dib->dibdev->parm->urb_buf_size*dib->dibdev->parm->num_urbs,dib->buffer,
+ dib->dma_handle);
return 0;
}
static int dibusb_init(struct usb_dibusb *dib)
{
- int ret,i;
+ int ret,i,bufsize;
sema_init(&dib->usb_sem, 1);
sema_init(&dib->i2c_sem, 1);
@@ -574,45 +540,51 @@ static int dibusb_init(struct usb_dibusb *dib)
* when reloading the driver w/o replugging the device
* a timeout occures, this helps
*/
- usb_clear_halt(dib->udev,COMMAND_PIPE);
- usb_clear_halt(dib->udev,RESULT_PIPE);
- usb_clear_halt(dib->udev,DATA_PIPE);
+ usb_clear_halt(dib->udev,usb_sndbulkpipe(dib->udev,dib->dibdev->parm->cmd_pipe));
+ usb_clear_halt(dib->udev,usb_rcvbulkpipe(dib->udev,dib->dibdev->parm->result_pipe));
+ usb_clear_halt(dib->udev,usb_rcvbulkpipe(dib->udev,dib->dibdev->parm->data_pipe));
- /* dibusb_reset_cpu(dib); */
-
- if ((dib->buffer = pci_alloc_consistent(NULL,DIBUSB_TS_BUFFER_SIZE, &dib->dma_handle)) == NULL) {
+ /* allocate the array for the data transfer URBs */
+ dib->urb_list = kmalloc(dib->dibdev->parm->num_urbs*sizeof(struct urb *),GFP_KERNEL);
+ if (dib->urb_list == NULL)
+ return -ENOMEM;
+ memset(dib->urb_list,0,dib->dibdev->parm->num_urbs*sizeof(struct urb *));
+
+ bufsize = dib->dibdev->parm->num_urbs*dib->dibdev->parm->urb_buf_size;
+ deb_info("allocate %d bytes as buffersize for all URBs\n",bufsize);
+ /* allocate the actual buffer for the URBs */
+ if ((dib->buffer = pci_alloc_consistent(NULL,bufsize,&dib->dma_handle)) == NULL) {
+ dibusb_exit(dib);
return -ENOMEM;
}
- memset(dib->buffer,0,DIBUSB_TS_BUFFER_SIZE);
- for (i = 0; i < DIBUSB_TS_NUM_URBS; i++) {
- if (!(dib->buf_urb[i] = usb_alloc_urb(0,GFP_KERNEL))) {
+ memset(dib->buffer,0,bufsize);
+
+ /* allocate and submit the URBs */
+ for (i = 0; i < dib->dibdev->parm->num_urbs; i++) {
+ if (!(dib->urb_list[i] = usb_alloc_urb(0,GFP_KERNEL))) {
dibusb_exit(dib);
return -ENOMEM;
}
deb_info("submitting URB no. %d\n",i);
- usb_fill_bulk_urb( dib->buf_urb[i], dib->udev, DATA_PIPE,
- &dib->buffer[i*DIBUSB_TS_URB_BUFFER_SIZE], DIBUSB_TS_URB_BUFFER_SIZE,
+ usb_fill_bulk_urb( dib->urb_list[i], dib->udev,
+ usb_rcvbulkpipe(dib->udev,dib->dibdev->parm->data_pipe),
+ &dib->buffer[i*dib->dibdev->parm->urb_buf_size],
+ dib->dibdev->parm->urb_buf_size,
dibusb_urb_complete, dib);
- dib->buf_urb[i]->transfer_flags = 0;
+
+ dib->urb_list[i]->transfer_flags = 0;
+#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,7)
+ dib->urb_list[i]->timeout = 0;
+#endif
- if ((ret = usb_submit_urb(dib->buf_urb[i],GFP_KERNEL))) {
+ if ((ret = usb_submit_urb(dib->urb_list[i],GFP_KERNEL))) {
err("could not submit buffer urb no. %d\n",i);
dibusb_exit(dib);
return ret;
}
}
- dib->pid_list_lock = SPIN_LOCK_UNLOCKED;
- for (i=0; i < DIBUSB_MAX_PIDS; i++) {
- dib->pid_list[i].reg = i+DIB3000MB_REG_FIRST_PID;
- dib->pid_list[i].pid = 0;
- dib->pid_list[i].active = 0;
- dib->pid_list[i].dib = dib;
- }
-
- dib->feedcount = 0;
- dib->streaming = 0;
dib->dvb_is_ready = 0;
if ((ret = dibusb_dvb_init(dib))) {
@@ -635,17 +607,20 @@ static int dibusb_loadfirmware(struct usb_device *udev,
struct dibusb_device *dibdev)
{
const struct firmware *fw = NULL;
+ const char **fws;
u16 addr;
u8 *b,*p;
int ret = 0,i;
-
- for (i = 0; i < sizeof(valid_firmware_filenames)/sizeof(const char*); i++) {
- if ((ret = request_firmware(&fw, valid_firmware_filenames[i], &udev->dev)) == 0) {
- info("using firmware file (%s).",valid_firmware_filenames[i]);
+
+ fws = dibdev->parm->fw_filenames;
+
+ for (i = 0; i < sizeof(fws)/sizeof(const char*); i++) {
+ if ((ret = request_firmware(&fw, fws[i], &udev->dev)) == 0) {
+ info("using firmware file (%s).",fws[i]);
break;
}
deb_info("tried to find '%s' firmware - unsuccessful. (%d)\n",
- valid_firmware_filenames[i],ret);
+ fws[i],ret);
}
if (fw == NULL) {
@@ -665,7 +640,7 @@ static int dibusb_loadfirmware(struct usb_device *udev,
/* stop the CPU */
reset = 1;
- if ((ret = dibusb_writemem(udev,DIBUSB_CPU_CSREG,&reset,1)) != 1)
+ if ((ret = dibusb_writemem(udev,dibdev->parm->usb_cpu_csreg,&reset,1)) != 1)
err("could not stop the USB controller CPU.");
for(i = 0; p[i+3] == 0 && i < fw->size; ) {
b = (u8 *) &p[i];
@@ -687,7 +662,7 @@ static int dibusb_loadfirmware(struct usb_device *udev,
ret = 0;
/* restart the CPU */
reset = 0;
- if (ret || dibusb_writemem(udev,DIBUSB_CPU_CSREG,&reset,1) != 1) {
+ if (ret || dibusb_writemem(udev,dibdev->parm->usb_cpu_csreg,&reset,1) != 1) {
err("could not restart the USB controller CPU.");
ret = -EINVAL;
}
@@ -735,6 +710,21 @@ static int dibusb_probe(struct usb_interface *intf,
if (cold)
ret = dibusb_loadfirmware(udev,dibdev);
else {
+ switch (udev->speed) {
+ case USB_SPEED_LOW:
+ err("cannot handle USB speed because it is to sLOW.");
+ break;
+ case USB_SPEED_FULL:
+ info("running at FULL speed, will use pid filter.");
+ break;
+ case USB_SPEED_HIGH:
+ info("running at HIGH speed, will deliver the complete TS.");
+ break;
+ case USB_SPEED_UNKNOWN: /* fall through */
+ default:
+ err("cannot handle USB speed because it is unkown.");
+ break;
+ }
dib = kmalloc(sizeof(struct usb_dibusb),GFP_KERNEL);
if (dib == NULL) {
err("no memory");
@@ -748,6 +738,7 @@ static int dibusb_probe(struct usb_interface *intf,
usb_set_intfdata(intf, dib);
ret = dibusb_init(dib);
+
}
if (ret == 0)
diff --git a/linux/drivers/media/dvb/dibusb/dvb-dibusb.h b/linux/drivers/media/dvb/dibusb/dvb-dibusb.h
index b2b12a774..5431cd251 100644
--- a/linux/drivers/media/dvb/dibusb/dvb-dibusb.h
+++ b/linux/drivers/media/dvb/dibusb/dvb-dibusb.h
@@ -13,127 +13,239 @@
#ifndef __DVB_DIBUSB_H__
#define __DVB_DIBUSB_H__
-#define DIBUSB_DEMOD_I2C_ADDR_DEFAULT 0x10
+#include "dib3000.h"
-/* Vendor IDs */
-#define USB_VID_TWINHAN_ID 0x1822
-#define USB_VID_IMC_NETWORKS_ID 0x13d3
-#define USB_VID_EMPIA_ID 0xeb1a
-#define USB_VID_DIBCOM_ID 0x10b8
-#define USB_VID_ULTIMA_ELECTRONIC_ID 0x05d8
-#define USB_VID_COMPRO_ID 0x185b
-#define USB_VID_HYPER_PALTEK 0x1025
+typedef enum {
+ DIBUSB1_1 = 0,
+ DIBUSB2_0,
+ DIBUSB1_1_AN2235,
+} dibusb_type;
+
+static const char * dibusb_fw_filenames1_1[] = {
+ "dvb-dibusb-5.0.0.11.fw"
+};
+
+static const char * dibusb_fw_filenames1_1_an2235[] = {
+};
-/* Product IDs before loading the firmware */
-#define USB_PID_TWINHAN_VP7041_COLD_ID 0x3201
-#define USB_PID_KWORLD_VSTREAM_COLD_ID 0x17de
-#define USB_PID_DIBCOM_MOD3000_COLD_ID 0x0bb8
-#define USB_PID_ULTIMA_TVBOX_COLD_ID 0x8105
-#define USB_PID_COMPRO_DVBU2000_COLD_ID 0xd000
-#define USB_PID_UNK_HYPER_PALTEK_COLD_ID 0x005e
-
-/* product ID afterwards */
-#define USB_PID_TWINHAN_VP7041_WARM_ID 0x3202
-#define USB_PID_KWORLD_VSTREAM_WARM_ID 0x17df
-#define USB_PID_DIBCOM_MOD3000_WARM_ID 0x0bb9
-#define USB_PID_ULTIMA_TVBOX_WARM_ID 0x8106
-#define USB_PID_COMPRO_DVBU2000_WARM_ID 0xd001
-#define USB_PID_UNK_HYPER_PALTEK_WARM_ID 0x005f
-
-/* static array of valid firmware names, the best one first */
-static const char * valid_firmware_filenames[] = {
- "dvb-dibusb-5.0.0.11.fw",
+static const char * dibusb_fw_filenames2_0[] = {
+ "dvb-dibusb-6.0.0.5.fw"
+};
+
+struct dibusb_device_parameter {
+ dibusb_type type;
+ u8 demod_addr;
+ const char **fw_filenames;
+ const char *usb_controller;
+ u16 usb_cpu_csreg;
+
+ int num_urbs;
+ int urb_buf_size;
+ int default_size;
+ int firmware_bug;
+
+ int cmd_pipe;
+ int result_pipe;
+ int data_pipe;
+};
+
+static struct dibusb_device_parameter dibusb_dev_parm[3] = {
+ { .type = DIBUSB1_1,
+ .demod_addr = 0x10,
+ .fw_filenames = dibusb_fw_filenames1_1,
+ .usb_controller = "Cypress AN2135",
+ .usb_cpu_csreg = 0x7f92,
+
+ .num_urbs = 3,
+ .urb_buf_size = 4096,
+ .default_size = 188*21,
+ .firmware_bug = 1,
+
+ .cmd_pipe = 0x01,
+ .result_pipe = 0x81,
+ .data_pipe = 0x82,
+ },
+ { .type = DIBUSB2_0,
+ .demod_addr = 0x10,
+ .fw_filenames = dibusb_fw_filenames2_0,
+ .usb_controller = "Cypress FX2",
+ .usb_cpu_csreg = 0xe600,
+
+ .num_urbs = 3,
+ .urb_buf_size = 40960,
+ .default_size = 188*210,
+ .firmware_bug = 0,
+
+ .cmd_pipe = 0x01,
+ .result_pipe = 0x81,
+ .data_pipe = 0x86,
+ },
+ { .type = DIBUSB1_1_AN2235,
+ .demod_addr = 0x10,
+ .fw_filenames = dibusb_fw_filenames1_1_an2235,
+ .usb_controller = "Cypress CY7C64613 (AN2235)",
+ .usb_cpu_csreg = 0x7f92,
+
+ .num_urbs = 3,
+ .urb_buf_size = 4096,
+ .default_size = 188*21,
+ .firmware_bug = 1,
+
+ .cmd_pipe = 0x01,
+ .result_pipe = 0x81,
+ .data_pipe = 0x82,
+ }
};
struct dibusb_device {
+ const char *name;
u16 cold_product_id;
u16 warm_product_id;
- u8 demod_addr;
- const char *name;
+ struct dibusb_device_parameter *parm;
};
-#define DIBUSB_SUPPORTED_DEVICES 6
+/* Vendor IDs */
+#define USB_VID_ANCHOR 0x0574
+#define USB_VID_AVERMEDIA 0x14aa
+#define USB_VID_COMPRO 0x185b
+#define USB_VID_DIBCOM 0x10b8
+#define USB_VID_EMPIA 0xeb1a
+#define USB_VID_GRANDTEC 0x5032
+#define USB_VID_HYPER_PALTEK 0x1025
+#define USB_VID_IMC_NETWORKS 0x13d3
+#define USB_VID_TWINHAN 0x1822
+#define USB_VID_ULTIMA_ELECTRONIC 0x05d8
+
+/* Product IDs */
+#define USB_PID_AVERMEDIA_DVBT_USB_COLD 0x0001
+#define USB_PID_AVERMEDIA_DVBT_USB_WARM 0x0002
+#define USB_PID_COMPRO_DVBU2000_COLD 0xd000
+#define USB_PID_COMPRO_DVBU2000_WARM 0xd001
+#define USB_PID_DIBCOM_MOD3000_COLD 0x0bb8
+#define USB_PID_DIBCOM_MOD3000_WARM 0x0bb9
+#define USB_PID_DIBCOM_MOD3001_COLD 0x0bc6
+#define USB_PID_DIBCOM_MOD3001_WARM 0x0bc7
+#define USB_PID_GRANDTEC_DVBT_USB_COLD 0x0fa0
+#define USB_PID_GRANDTEC_DVBT_USB_WARM 0x0fa1
+#define USB_PID_KWORLD_VSTREAM_COLD 0x17de
+#define USB_PID_KWORLD_VSTREAM_WARM 0x17df
+#define USB_PID_TWINHAN_VP7041_COLD 0x3201
+#define USB_PID_TWINHAN_VP7041_WARM 0x3202
+#define USB_PID_ULTIMA_TVBOX_COLD 0x8105
+#define USB_PID_ULTIMA_TVBOX_WARM 0x8106
+#define USB_PID_ULTIMA_TVBOX_AN2235_COLD 0x8107
+#define USB_PID_ULTIMA_TVBOX_AN2235_WARM 0x8108
+#define USB_PID_ULTIMA_TVBOX_ANCHOR_COLD 0x2235
+#define USB_PID_UNK_HYPER_PALTEK_COLD 0x005e
+#define USB_PID_UNK_HYPER_PALTEK_WARM 0x005f
+#define USB_PID_YAKUMO_DTT200U_COLD 0x0201
+#define USB_PID_YAKUMO_DTT200U_WARM 0x0301
+
+#define DIBUSB_SUPPORTED_DEVICES 12
/* USB Driver stuff */
static struct dibusb_device dibusb_devices[DIBUSB_SUPPORTED_DEVICES] = {
- { .cold_product_id = USB_PID_TWINHAN_VP7041_COLD_ID,
- .warm_product_id = USB_PID_TWINHAN_VP7041_WARM_ID,
- .name = "TwinhanDTV USB-Ter/Magic Box / HAMA USB DVB-T device",
- .demod_addr = DIBUSB_DEMOD_I2C_ADDR_DEFAULT,
+ { .name = "TwinhanDTV USB1.1 / Magic Box / HAMA USB1.1 DVB-T device",
+ .cold_product_id = USB_PID_TWINHAN_VP7041_COLD,
+ .warm_product_id = USB_PID_TWINHAN_VP7041_WARM,
+ .parm = &dibusb_dev_parm[0],
+ },
+ { .name = "KWorld V-Stream XPERT DTV - DVB-T USB1.1",
+ .cold_product_id = USB_PID_KWORLD_VSTREAM_COLD,
+ .warm_product_id = USB_PID_KWORLD_VSTREAM_WARM,
+ .parm = &dibusb_dev_parm[0],
},
- { .cold_product_id = USB_PID_KWORLD_VSTREAM_COLD_ID,
- .warm_product_id = USB_PID_KWORLD_VSTREAM_WARM_ID,
- .name = "KWorld V-Stream XPERT DTV - DVB-T USB",
- .demod_addr = DIBUSB_DEMOD_I2C_ADDR_DEFAULT,
+ { .name = "Grandtec USB1.1 DVB-T/DiBcom USB1.1 DVB-T reference design (MOD3000)",
+ .cold_product_id = USB_PID_DIBCOM_MOD3000_COLD,
+ .warm_product_id = USB_PID_DIBCOM_MOD3000_WARM,
+ .parm = &dibusb_dev_parm[0],
},
- { .cold_product_id = USB_PID_DIBCOM_MOD3000_COLD_ID,
- .warm_product_id = USB_PID_DIBCOM_MOD3000_WARM_ID,
- .name = "DiBcom USB DVB-T reference design (MOD300)",
- .demod_addr = DIBUSB_DEMOD_I2C_ADDR_DEFAULT,
+ { .name = "Artec T1 USB1.1 TVBOX with AN2135",
+ .cold_product_id = USB_PID_ULTIMA_TVBOX_COLD,
+ .warm_product_id = USB_PID_ULTIMA_TVBOX_WARM,
+ .parm = &dibusb_dev_parm[0],
},
- { .cold_product_id = USB_PID_ULTIMA_TVBOX_COLD_ID,
- .warm_product_id = USB_PID_ULTIMA_TVBOX_WARM_ID,
- .name = "Ultima Electronic/Artec T1 USB TVBOX",
- .demod_addr = DIBUSB_DEMOD_I2C_ADDR_DEFAULT,
+ { .name = "Artec T1 USB1.1 TVBOX with AN2235",
+ .cold_product_id = USB_PID_ULTIMA_TVBOX_AN2235_COLD,
+ .warm_product_id = USB_PID_ULTIMA_TVBOX_AN2235_WARM,
+ .parm = &dibusb_dev_parm[2],
},
- { .cold_product_id = USB_PID_COMPRO_DVBU2000_COLD_ID,
- .warm_product_id = USB_PID_COMPRO_DVBU2000_WARM_ID,
- .name = "Compro Videomate DVB-U2000 - DVB-T USB",
- .demod_addr = DIBUSB_DEMOD_I2C_ADDR_DEFAULT,
+ { .name = "Artec T1 USB1.1 TVBOX with AN2235 (misdesigned)",
+ .cold_product_id = USB_PID_ULTIMA_TVBOX_ANCHOR_COLD,
+ .warm_product_id = 0, /* undefined, this design becomes USB_PID_DIBCOM_MOD3000_WARM in warm state */
+ .parm = &dibusb_dev_parm[2],
},
- { .cold_product_id = USB_PID_UNK_HYPER_PALTEK_COLD_ID,
- .warm_product_id = USB_PID_UNK_HYPER_PALTEK_WARM_ID,
- .name = "Unkown USB DVB-T device ???? please report the name to linux-dvb or to the author",
- .demod_addr = DIBUSB_DEMOD_I2C_ADDR_DEFAULT,
+ { .name = "Compro Videomate DVB-U2000 - DVB-T USB1.1",
+ .cold_product_id = USB_PID_COMPRO_DVBU2000_COLD,
+ .warm_product_id = USB_PID_COMPRO_DVBU2000_WARM,
+ .parm = &dibusb_dev_parm[0],
+ },
+ { .name = "Unkown USB1.1 DVB-T device ???? please report the name to the author",
+ .cold_product_id = USB_PID_UNK_HYPER_PALTEK_COLD,
+ .warm_product_id = USB_PID_UNK_HYPER_PALTEK_WARM,
+ .parm = &dibusb_dev_parm[0],
+ },
+ { .name = "DiBcom USB2.0 DVB-T reference design (MOD3000P)",
+ .cold_product_id = USB_PID_DIBCOM_MOD3001_COLD,
+ .warm_product_id = USB_PID_DIBCOM_MOD3001_WARM,
+ .parm = &dibusb_dev_parm[1],
+ },
+ { .name = "Grandtec DVB-T USB1.1",
+ .cold_product_id = USB_PID_GRANDTEC_DVBT_USB_COLD,
+ .warm_product_id = USB_PID_GRANDTEC_DVBT_USB_WARM,
+ .parm = &dibusb_dev_parm[0],
+ },
+ { .name = "Avermedia AverTV DVBT USB1.1",
+ .cold_product_id = USB_PID_AVERMEDIA_DVBT_USB_COLD,
+ .warm_product_id = USB_PID_AVERMEDIA_DVBT_USB_WARM,
+ .parm = &dibusb_dev_parm[0],
+ },
+ { .name = "Yakumo DVB-T mobile USB2.0",
+ .cold_product_id = USB_PID_YAKUMO_DTT200U_COLD,
+ .warm_product_id = USB_PID_YAKUMO_DTT200U_WARM,
+ .parm = &dibusb_dev_parm[1],
}
};
/* USB Driver stuff */
/* table of devices that work with this driver */
static struct usb_device_id dibusb_table [] = {
- { USB_DEVICE(USB_VID_TWINHAN_ID, USB_PID_TWINHAN_VP7041_COLD_ID) },
- { USB_DEVICE(USB_VID_TWINHAN_ID, USB_PID_TWINHAN_VP7041_WARM_ID) },
- { USB_DEVICE(USB_VID_IMC_NETWORKS_ID,USB_PID_TWINHAN_VP7041_COLD_ID) },
- { USB_DEVICE(USB_VID_IMC_NETWORKS_ID,USB_PID_TWINHAN_VP7041_WARM_ID) },
- { USB_DEVICE(USB_VID_EMPIA_ID, USB_PID_KWORLD_VSTREAM_COLD_ID) },
- { USB_DEVICE(USB_VID_EMPIA_ID, USB_PID_KWORLD_VSTREAM_WARM_ID) },
- { USB_DEVICE(USB_VID_DIBCOM_ID, USB_PID_DIBCOM_MOD3000_COLD_ID) },
- { USB_DEVICE(USB_VID_DIBCOM_ID, USB_PID_DIBCOM_MOD3000_WARM_ID) },
- { USB_DEVICE(USB_VID_ULTIMA_ELECTRONIC_ID, USB_PID_ULTIMA_TVBOX_COLD_ID) },
- { USB_DEVICE(USB_VID_ULTIMA_ELECTRONIC_ID, USB_PID_ULTIMA_TVBOX_WARM_ID) },
- { USB_DEVICE(USB_VID_COMPRO_ID, USB_PID_COMPRO_DVBU2000_COLD_ID) },
- { USB_DEVICE(USB_VID_COMPRO_ID, USB_PID_COMPRO_DVBU2000_WARM_ID) },
- { USB_DEVICE(USB_VID_HYPER_PALTEK, USB_PID_UNK_HYPER_PALTEK_COLD_ID) },
- { USB_DEVICE(USB_VID_HYPER_PALTEK, USB_PID_UNK_HYPER_PALTEK_WARM_ID) },
+ { USB_DEVICE(USB_VID_AVERMEDIA, USB_PID_AVERMEDIA_DVBT_USB_COLD)},
+ { USB_DEVICE(USB_VID_AVERMEDIA, USB_PID_AVERMEDIA_DVBT_USB_WARM)},
+ { USB_DEVICE(USB_VID_COMPRO, USB_PID_COMPRO_DVBU2000_COLD) },
+ { USB_DEVICE(USB_VID_COMPRO, USB_PID_COMPRO_DVBU2000_WARM) },
+ { USB_DEVICE(USB_VID_DIBCOM, USB_PID_DIBCOM_MOD3000_COLD) },
+ { USB_DEVICE(USB_VID_DIBCOM, USB_PID_DIBCOM_MOD3000_WARM) },
+ { USB_DEVICE(USB_VID_DIBCOM, USB_PID_DIBCOM_MOD3001_COLD) },
+ { USB_DEVICE(USB_VID_DIBCOM, USB_PID_DIBCOM_MOD3001_WARM) },
+ { USB_DEVICE(USB_VID_EMPIA, USB_PID_KWORLD_VSTREAM_COLD) },
+ { USB_DEVICE(USB_VID_EMPIA, USB_PID_KWORLD_VSTREAM_WARM) },
+ { USB_DEVICE(USB_VID_GRANDTEC, USB_PID_GRANDTEC_DVBT_USB_COLD) },
+ { USB_DEVICE(USB_VID_GRANDTEC, USB_PID_GRANDTEC_DVBT_USB_WARM) },
+ { USB_DEVICE(USB_VID_GRANDTEC, USB_PID_DIBCOM_MOD3000_COLD) },
+ { USB_DEVICE(USB_VID_GRANDTEC, USB_PID_DIBCOM_MOD3000_WARM) },
+ { USB_DEVICE(USB_VID_HYPER_PALTEK, USB_PID_UNK_HYPER_PALTEK_COLD) },
+ { USB_DEVICE(USB_VID_HYPER_PALTEK, USB_PID_UNK_HYPER_PALTEK_WARM) },
+ { USB_DEVICE(USB_VID_IMC_NETWORKS, USB_PID_TWINHAN_VP7041_COLD) },
+ { USB_DEVICE(USB_VID_IMC_NETWORKS, USB_PID_TWINHAN_VP7041_WARM) },
+ { USB_DEVICE(USB_VID_TWINHAN, USB_PID_TWINHAN_VP7041_COLD) },
+ { USB_DEVICE(USB_VID_TWINHAN, USB_PID_TWINHAN_VP7041_WARM) },
+ { USB_DEVICE(USB_VID_ULTIMA_ELECTRONIC, USB_PID_ULTIMA_TVBOX_COLD) },
+ { USB_DEVICE(USB_VID_ULTIMA_ELECTRONIC, USB_PID_ULTIMA_TVBOX_WARM) },
+ { USB_DEVICE(USB_VID_ULTIMA_ELECTRONIC, USB_PID_ULTIMA_TVBOX_AN2235_COLD) },
+ { USB_DEVICE(USB_VID_ULTIMA_ELECTRONIC, USB_PID_ULTIMA_TVBOX_AN2235_WARM) },
+ { USB_DEVICE(USB_VID_AVERMEDIA, USB_PID_YAKUMO_DTT200U_COLD) },
+ { USB_DEVICE(USB_VID_AVERMEDIA, USB_PID_YAKUMO_DTT200U_WARM) },
+// #define CONFIG_DVB_DIBUSB_MISDESIGNED_AN2235
+#ifdef CONFIG_DVB_DIBUSB_MISDESIGNED_AN2235
+ { USB_DEVICE(USB_VID_ANCHOR, USB_PID_ULTIMA_TVBOX_ANCHOR_COLD) },
+#endif
{ } /* Terminating entry */
};
MODULE_DEVICE_TABLE (usb, dibusb_table);
-/* CS register start/stop the usb controller cpu */
-#define DIBUSB_CPU_CSREG 0x7F92
-
-// 0x10 is the I2C address of the first demodulator on the board
-#define DIBUSB_DEMOD_I2C_ADDR_DEFAULT 0x10
-#define DIBUSB_I2C_TIMEOUT HZ*5
-
-#define DIBUSB_MAX_PIDS 16
-
-#define DIB3000MB_REG_FIRST_PID ( 153)
-
-struct usb_dibusb;
-
-struct dibusb_pid {
- u16 reg;
- u16 pid;
- int active;
- struct usb_dibusb *dib;
-};
-
-#define DIBUSB_TS_NUM_URBS 3
-#define DIBUSB_TS_URB_BUFFER_SIZE 4096
-#define DIBUSB_TS_BUFFER_SIZE (DIBUSB_TS_NUM_URBS * DIBUSB_TS_URB_BUFFER_SIZE)
-#define DIBUSB_TS_DEFAULT_SIZE (188*21)
+#define DIBUSB_I2C_TIMEOUT HZ*5
struct usb_dibusb {
/* usb */
@@ -142,14 +254,12 @@ struct usb_dibusb {
struct dibusb_device * dibdev;
int feedcount;
- int streaming;
- struct urb * buf_urb[DIBUSB_TS_NUM_URBS];
+ struct dib3000_xfer_ops xfer_ops;
+
+ struct urb **urb_list;
u8 *buffer;
dma_addr_t dma_handle;
- spinlock_t pid_list_lock;
- struct dibusb_pid pid_list[DIBUSB_MAX_PIDS];
-
/* I2C */
struct i2c_adapter i2c_adap;
struct i2c_client i2c_client;
@@ -167,14 +277,6 @@ struct usb_dibusb {
struct dvb_frontend* fe;
};
-#define COMMAND_PIPE usb_sndbulkpipe(dib->udev, 0x01)
-#define RESULT_PIPE usb_rcvbulkpipe(dib->udev, 0x81)
-#define DATA_PIPE usb_rcvbulkpipe(dib->udev, 0x82)
-/*
- * last endpoint 0x83 only used for chaining the buffers
- * of the endpoints in the cypress
- */
-#define CHAIN_PIPE_DO_NOT_USE usb_rcvbulkpipe(dib->udev, 0x83)
/* types of first byte of each buffer */
@@ -208,16 +310,4 @@ struct usb_dibusb {
#define DIBUSB_IOCTL_POWER_SLEEP 0x00
#define DIBUSB_IOCTL_POWER_WAKEUP 0x01
-
-/*
- * values from the demodulator which are needed in
- * the usb driver as well
- */
-
-#define DIB3000MB_REG_FIFO ( 145)
-#define DIB3000MB_FIFO_INHIBIT ( 1)
-#define DIB3000MB_FIFO_ACTIVATE ( 0)
-
-#define DIB3000MB_ACTIVATE_FILTERING (0x2000)
-
#endif