2004-10-27 09:59:52

by Michael Hunold

[permalink] [raw]
Subject: [PATCH][0/5] Update the DVB subsystem

Hi again,

thanks for applying the recent DVB updates to 2.6.10-rc1.

Here comes another patchset with 5 patches that in short does the following:

- rework debug print logic in av7110 driver
- various fixes in the dvb-core
- one new driver named "Terratec CinergyT2/qanu" for an highspeed USB2
DVB-T receiver
- general overhaul of the dibusb USB DVB driver -- there are more clones
of this card out there than we expected

As usual, the details are at the top of each patch. IMO all changes are
non-intrusive and can be applied safely.

Please apply.

CU
Michael.


2004-10-27 09:57:53

by Michael Hunold

[permalink] [raw]
Subject: [PATCH][1/5] DVB: rework debugging in av7110

- [DVB] av7110: switch from stupid DEB_xx() debug macros to saner dprintk() style debugging
- [DVB] av7110: fix dvb-ttpci ca write() polling
- [DVB] budget: switch from stupid DEB_xx() debug macros to saner dprintk() style debugging

Signed-off-by: Michael Hunold <[email protected]>

diff -uraNwB linux-2.6.10-rc1/drivers/media/dvb/ttpci/av7110.c linux-2.6.10-rc1-patched/drivers/media/dvb/ttpci/av7110.c
--- linux-2.6.10-rc1/drivers/media/dvb/ttpci/av7110.c 2004-10-25 14:07:52.000000000 +0200
+++ linux-2.6.10-rc1-patched/drivers/media/dvb/ttpci/av7110.c 2004-10-25 14:14:43.000000000 +0200
@@ -67,7 +67,8 @@
#include "av7110_ca.h"
#include "av7110_ipack.h"

-static int av7110_debug;
+int av7110_debug;
+
static int vidmode=CVBS_RGB_OUT;
static int pids_off;
static int adac=DVB_ADAC_TI;
@@ -110,7 +111,7 @@
av7110->has_analog_tuner = 0;
av7110->current_input = 0;
if (i2c_writereg(av7110, 0x20, 0x00, 0x00) == 1) {
- printk ("av7110(%d): Crystal audio DAC detected\n",
+ printk ("dvb-ttpci: Crystal audio DAC @ card %d detected\n",
av7110->dvb_adapter->num);
av7110->adac_type = DVB_ADAC_CRYSTAL;
i2c_writereg(av7110, 0x20, 0x01, 0xd2);
@@ -125,13 +126,13 @@
/* done. */
}
else if (dev->pci->subsystem_vendor == 0x110a) {
- printk("av7110(%d): DVB-C w/o analog module detected\n",
+ printk("dvb-ttpci: DVB-C w/o analog module @ card %d detected\n",
av7110->dvb_adapter->num);
av7110->adac_type = DVB_ADAC_NONE;
}
else {
av7110->adac_type = adac;
- printk("av7110(%d): adac type set to %d\n",
+ printk("dvb-ttpci: adac type set to %d @ card %d\n",
av7110->dvb_adapter->num, av7110->adac_type);
}

@@ -150,7 +151,7 @@

static void recover_arm(struct av7110 *av7110)
{
- DEB_EE(("av7110: %p\n",av7110));
+ dprintk(4, "%p\n",av7110);

av7110_bootarm(av7110);
msleep(100);
@@ -160,7 +161,7 @@

static void arm_error(struct av7110 *av7110)
{
- DEB_EE(("av7110: %p\n",av7110));
+ dprintk(4, "%p\n",av7110);

av7110->arm_errors++;
av7110->arm_ready=0;
@@ -173,7 +174,7 @@
u16 newloops = 0;
int timeout;

- DEB_EE(("av7110: %p\n",av7110));
+ dprintk(4, "%p\n",av7110);

lock_kernel ();
daemonize ("arm_mon");
@@ -199,7 +200,7 @@
up(&av7110->dcomlock);

if (newloops==av7110->arm_loops) {
- printk(KERN_ERR "av7110%d: ARM crashed!\n",
+ printk(KERN_ERR "dvb-ttpci: ARM crashed @ card %d\n",
av7110->dvb_adapter->num);

arm_error(av7110);
@@ -231,7 +232,7 @@
{
static struct av7110 *last;

- DEB_EE(("av7110: %p\n",av7110));
+ dprintk(4, "%p\n",av7110);

if (!av7110)
av7110 = last;
@@ -248,13 +249,13 @@

void av7110_register_irc_handler(void (*func)(u32))
{
- DEB_EE(("registering %p\n", func));
+ dprintk(4, "registering %p\n", func);
irc_handler = func;
}

void av7110_unregister_irc_handler(void (*func)(u32))
{
- DEB_EE(("unregistering %p\n", func));
+ dprintk(4, "unregistering %p\n", func);
irc_handler = NULL;
}

@@ -268,7 +269,7 @@

void IR_handle(struct av7110 *av7110, u32 ircom)
{
- DEB_S(("av7110: ircommand = %08x\n", ircom));
+ dprintk(4, "ircommand = %08x\n", ircom);
irtask.data = (unsigned long) ircom;
tasklet_schedule(&irtask);
}
@@ -283,8 +284,6 @@
enum dmx_success success,
struct av7110 *av7110)
{
- DEB_INT(("av7110: %p\n",av7110));
-
if (!dvbdmxfilter->feed->demux->dmx.frontend)
return 0;
if (dvbdmxfilter->feed->demux->dmx.frontend->source==DMX_MEMORY_FE)
@@ -344,7 +343,7 @@
int type=av7110->debitype;
int handle=(type>>8)&0x1f;

-// DEB_EE(("av7110: %p\n",av7110));
+// dprintk(4, "%p\n",av7110);

print_time("debi");
saa7146_write(av7110->dev, IER,
@@ -476,10 +475,8 @@
u32 rxbuf, txbuf;
int len;

- //printk("GPIO0 irq\n");
-
if (av7110->debitype !=-1)
- printk("GPIO0 irq oops @ %ld, psr:0x%08x, ssr:0x%08x\n",
+ printk("dvb-ttpci: GPIO0 irq oops @ %ld, psr:0x%08x, ssr:0x%08x\n",
jiffies, saa7146_read(av7110->dev, PSR),
saa7146_read(av7110->dev, SSR));

@@ -497,10 +494,10 @@
txbuf=irdebi(av7110, DEBINOSWAP, TX_BUFF, 0, 2);
len = (av7110->debilen + 3) & ~3;

-// DEB_D(("GPIO0 irq %d %d\n", av7110->debitype, av7110->debilen));
+// dprintk(8, "GPIO0 irq %d %d\n", av7110->debitype, av7110->debilen);
print_time("gpio");

-// DEB_D(("GPIO0 irq %02x\n", av7110->debitype&0xff));
+// dprintk(8, "GPIO0 irq %02x\n", av7110->debitype&0xff);
switch (av7110->debitype&0xff) {

case DATA_TS_PLAY:
@@ -519,10 +516,10 @@
iwdebi(av7110, DEBINOSWAP, RX_BUFF, 0, 2);

av7110->video_size.h = h_ar & 0xfff;
- DEB_D(("GPIO0 irq: DATA_MPEG_VIDEO_EVENT: w/h/ar = %u/%u/%u\n",
+ dprintk(8, "GPIO0 irq: DATA_MPEG_VIDEO_EVENT: w/h/ar = %u/%u/%u\n",
av7110->video_size.w,
av7110->video_size.h,
- av7110->video_size.aspect_ratio));
+ av7110->video_size.aspect_ratio);

event.type = VIDEO_EVENT_SIZE_CHANGED;
event.u.size.w = av7110->video_size.w;
@@ -610,7 +607,7 @@
iwdebi(av7110, DEBINOSWAP, TX_BUFF, 0, 2);
break;
}
- DEB_D(("GPIO0 PES_PLAY len=%04x\n", len));
+ dprintk(8, "GPIO0 PES_PLAY len=%04x\n", len);
iwdebi(av7110, DEBINOSWAP, TX_LEN, len, 2);
iwdebi(av7110, DEBINOSWAP, IRQ_STATE_EXT, len, 2);
saa7146_wait_for_debi_done(av7110->dev);
@@ -688,7 +685,7 @@
break;

default:
- printk("gpioirq unknown type=%d len=%d\n",
+ printk("dvb-ttpci: gpioirq unknown type=%d len=%d\n",
av7110->debitype, av7110->debilen);
break;
}
@@ -705,7 +702,7 @@
struct dvb_device *dvbdev = (struct dvb_device *) file->private_data;
struct av7110 *av7110 = (struct av7110 *) dvbdev->priv;

- DEB_EE(("av7110: %p\n", av7110));
+ dprintk(4, "%p\n", av7110);

if (cmd == OSD_SEND_CMD)
return av7110_osd_cmd(av7110, (osd_cmd_t *) parg);
@@ -736,7 +733,7 @@
static inline int SetPIDs(struct av7110 *av7110, u16 vpid, u16 apid, u16 ttpid,
u16 subpid, u16 pcrpid)
{
- DEB_EE(("av7110: %p\n", av7110));
+ dprintk(4, "%p\n", av7110);

if (vpid == 0x1fff || apid == 0x1fff ||
ttpid == 0x1fff || subpid == 0x1fff || pcrpid == 0x1fff) {
@@ -754,7 +751,7 @@
void ChangePIDs(struct av7110 *av7110, u16 vpid, u16 apid, u16 ttpid,
u16 subpid, u16 pcrpid)
{
- DEB_EE(("av7110: %p\n", av7110));
+ dprintk(4, "%p\n", av7110);

if (down_interruptible(&av7110->pid_mutex))
return;
@@ -793,7 +790,7 @@
// u16 mode=0x0320;
u16 mode=0xb96a;

- DEB_EE(("av7110: %p\n",av7110));
+ dprintk(4, "%p\n", av7110);

if (dvbdmxfilter->type == DMX_TYPE_SEC) {
if (hw_sections) {
@@ -817,7 +814,7 @@

ret = av7110_fw_request(av7110, buf, 20, &handle, 1);
if (ret < 0) {
- printk("StartHWFilter error\n");
+ dprintk(1, "StartHWFilter error\n");
return ret;
}

@@ -835,13 +832,11 @@
int ret;
u16 handle;

- DEB_EE(("av7110: %p\n", av7110));
+ dprintk(4, "%p\n", av7110);

handle = dvbdmxfilter->hw_handle;
if (handle > 32) {
- DEB_S(("dvb: StopHWFilter tried to stop invalid filter %d.\n",
- handle));
- DEB_S(("dvb: filter type = %d\n", dvbdmxfilter->type));
+ dprintk(1, "StopHWFilter tried to stop invalid filter %d, filter type = %d\n", handle, dvbdmxfilter->type);
return 0;
}

@@ -852,10 +847,10 @@
buf[2] = handle;
ret = av7110_fw_request(av7110, buf, 3, answ, 2);
if (ret)
- printk("StopHWFilter error\n");
+ dprintk(1, "StopHWFilter error\n");

if (answ[1] != handle) {
- DEB_S(("dvb: filter %d shutdown error :%d\n", handle, answ[1]));
+ dprintk(2, "filter %d shutdown error :%d\n", handle, answ[1]);
ret = -1;
}
return ret;
@@ -869,7 +864,7 @@
u16 *pid = dvbdmx->pids, npids[5];
int i;

- DEB_EE(("av7110: %p\n",av7110));
+ dprintk(4, "%p\n", av7110);

npids[0] = npids[1] = npids[2] = npids[3] = npids[4] = 0xffff;
i = dvbdmxfeed->pes_type;
@@ -902,7 +897,7 @@
u16 *pid = dvbdmx->pids, npids[5];
int i;

- DEB_EE(("av7110: %p\n", av7110));
+ dprintk(4, "%p\n", av7110);

if (dvbdmxfeed->pes_type <= 1) {
av7110_av_stop(av7110, dvbdmxfeed->pes_type ? RP_VIDEO : RP_AUDIO);
@@ -935,7 +930,7 @@
struct dvb_demux *demux = feed->demux;
struct av7110 *av7110 = (struct av7110 *) demux->priv;

- DEB_EE(("av7110: %p\n", av7110));
+ dprintk(4, "%p\n", av7110);

if (!demux->dmx.frontend)
return -EINVAL;
@@ -993,7 +988,7 @@
struct dvb_demux *demux = feed->demux;
struct av7110 *av7110 = (struct av7110 *) demux->priv;

- DEB_EE(("av7110: %p\n",av7110));
+ dprintk(4, "%p\n", av7110);

if (feed->type == DMX_TYPE_TS) {
if (feed->ts_type & TS_DECODER) {
@@ -1035,7 +1030,7 @@
int mode;
int i;

- DEB_EE(("av7110: %p\n",av7110));
+ dprintk(4, "%p\n", av7110);

mode = av7110->playing;
av7110->playing = 0;
@@ -1068,7 +1063,7 @@
BUG();
av7110 = (struct av7110 *) dvbdemux->priv;

- DEB_EE(("av7110: %p\n",av7110));
+ dprintk(4, "%p\n", av7110);

if (num != 0)
return -EINVAL;
@@ -1078,14 +1073,14 @@
printk(KERN_ERR "%s: av7110_fw_request error\n", __FUNCTION__);
return -EIO;
}
- DEB_EE(("av7110: fwstc = %04hx %04hx %04hx %04hx\n",
- fwstc[0], fwstc[1], fwstc[2], fwstc[3]));
+ dprintk(2, "fwstc = %04hx %04hx %04hx %04hx\n",
+ fwstc[0], fwstc[1], fwstc[2], fwstc[3]);

*stc = (((uint64_t) ((fwstc[3] & 0x8000) >> 15)) << 32) |
(((uint64_t) fwstc[1]) << 16) | ((uint64_t) fwstc[0]);
*base = 1;

- DEB_EE(("av7110: stc = %lu\n", (unsigned long)*stc));
+ dprintk(4, "stc = %lu\n", (unsigned long)*stc);

return 0;
}
@@ -1099,7 +1094,7 @@
{
struct av7110 *av7110 = fe->before_after_data;

- DEB_EE(("av7110: %p\n", av7110));
+ dprintk(4, "%p\n", av7110);

switch (cmd) {
case FE_SET_TONE:
@@ -1138,7 +1133,7 @@
{
struct av7110 *av7110 = data;

- DEB_EE(("av7110: %p\n",av7110));
+ dprintk(4, "%p\n", av7110);

av7110->fe_synced = (s & FE_HAS_LOCK) ? 1 : 0;

@@ -1168,7 +1163,7 @@
int ret, i;
struct dvb_demux *dvbdemux=&av7110->demux;

- DEB_EE(("av7110: %p\n",av7110));
+ dprintk(4, "%p\n", av7110);

if (av7110->registered)
return -1;
@@ -1243,7 +1238,7 @@
{
struct dvb_demux *dvbdemux=&av7110->demux;

- DEB_EE(("av7110: %p\n",av7110));
+ dprintk(4, "%p\n", av7110);

if (!av7110->registered)
return;
@@ -1397,7 +1391,7 @@
/* check if the firmware is available */
av7110->bin_fw = (unsigned char*) vmalloc(fw->size);
if (NULL == av7110->bin_fw) {
- DEB_D(("out of memory\n"));
+ dprintk(1, "out of memory\n");
release_firmware(fw);
return -ENOMEM;
}
@@ -1440,14 +1434,14 @@
struct av7110 *av7110 = NULL;
int ret = 0;

- DEB_EE(("dev: %p\n", dev));
+ dprintk(4, "dev: %p\n", dev);

/* prepare the av7110 device struct */
if (!(av7110 = kmalloc (sizeof (struct av7110), GFP_KERNEL))) {
- printk ("%s: out of memory!\n", __FUNCTION__);
+ dprintk(1, "out of memory\n");
return -ENOMEM;
}
- DEB_EE(("av7110: %p\n", av7110));
+
memset(av7110, 0, sizeof(struct av7110));

av7110->card_name = (char*)pci_ext->ext_priv;
@@ -1547,11 +1541,11 @@
}

if (FW_VERSION(av7110->arm_app)<0x2501)
- printk ("av7110: Warning, firmware version 0x%04x is too old. "
+ printk ("dvb-ttpci: Warning, firmware version 0x%04x is too old. "
"System might be unstable!\n", FW_VERSION(av7110->arm_app));

if (kernel_thread(arm_thread, (void *) av7110, 0) < 0) {
- printk(KERN_ERR "av7110(%d): faile to start arm_mon kernel thread\n",
+ printk("dvb-ttpci: failed to start arm_mon kernel thread @ card %d\n",
av7110->dvb_adapter->num);
goto err2;
}
@@ -1572,7 +1566,7 @@
if (ret)
goto err3;

- printk(KERN_INFO "av7110: found av7110-%d.\n",av7110_num);
+ printk(KERN_INFO "dvb-ttpci: found av7110-%d.\n", av7110_num);
av7110->device_initialized = 1;
av7110_num++;
return 0;
@@ -1604,7 +1598,7 @@
static int av7110_detach (struct saa7146_dev* saa)
{
struct av7110 *av7110 = (struct av7110*)saa->ext_priv;
- DEB_EE(("av7110: %p\n",av7110));
+ dprintk(4, "%p\n", av7110);

if( 0 == av7110->device_initialized ) {
return 0;
@@ -1653,8 +1647,6 @@
{
struct av7110 *av7110 = (struct av7110*)dev->ext_priv;

-// DEB_INT(("dev: %p, av7110: %p\n",dev,av7110));
-
if (*isr & MASK_19)
tasklet_schedule (&av7110->debi_tasklet);

diff -uraNwB linux-2.6.10-rc1/drivers/media/dvb/ttpci/av7110.h linux-2.6.10-rc1-patched/drivers/media/dvb/ttpci/av7110.h
--- linux-2.6.10-rc1/drivers/media/dvb/ttpci/av7110.h 2004-10-25 14:07:51.000000000 +0200
+++ linux-2.6.10-rc1-patched/drivers/media/dvb/ttpci/av7110.h 2004-10-25 14:14:43.000000000 +0200
@@ -27,6 +27,11 @@

#include <media/saa7146_vv.h>

+extern int av7110_debug;
+
+#define dprintk(level,args...) \
+ do { if ((av7110_debug & level)) { printk("dvb-ttpci: %s(): ", __FUNCTION__); printk(args); } } while (0)
+
#define MAXFILT 32

enum {AV_PES_STREAM, PS_STREAM, TS_STREAM, PES_STREAM};
diff -uraNwB linux-2.6.10-rc1/drivers/media/dvb/ttpci/av7110_av.c linux-2.6.10-rc1-patched/drivers/media/dvb/ttpci/av7110_av.c
--- linux-2.6.10-rc1/drivers/media/dvb/ttpci/av7110_av.c 2004-10-25 14:07:52.000000000 +0200
+++ linux-2.6.10-rc1-patched/drivers/media/dvb/ttpci/av7110_av.c 2004-10-25 14:14:43.000000000 +0200
@@ -98,8 +97,6 @@
{
struct dvb_demux_feed *dvbdmxfeed = (struct dvb_demux_feed *) p2t->priv;

-// DEB_EE(("struct dvb_filter_pes2ts:%p\n", p2t));
-
if (!(dvbdmxfeed->ts_type & TS_PACKET))
return 0;
if (buf[3] == 0xe0) // video PES do not have a length in TS
@@ -115,8 +112,6 @@
{
struct dvb_demux_feed *dvbdmxfeed = (struct dvb_demux_feed *) priv;

-// DEB_EE(("dvb_demux_feed:%p\n", dvbdmxfeed));
-
dvbdmxfeed->cb.ts(data, 188, NULL, 0,
&dvbdmxfeed->feed.ts, DMX_OK);
return 0;
@@ -127,7 +122,7 @@
{
struct dvb_demux *dvbdmx = dvbdmxfeed->demux;

- DEB_EE(("av7110: %p, dvb_demux_feed:%p\n", av7110, dvbdmxfeed));
+ dprintk(2, "av7110:%p, , dvb_demux_feed:%p\n", av7110, dvbdmxfeed);

if (av7110->playing || (av7110->rec_mode & av))
return -EBUSY;
@@ -169,7 +164,7 @@

int av7110_av_start_play(struct av7110 *av7110, int av)
{
- DEB_EE(("av7110: %p\n", av7110));
+ dprintk(2, "av7110:%p, \n", av7110);

if (av7110->rec_mode)
return -EBUSY;
@@ -202,7 +197,7 @@

void av7110_av_stop(struct av7110 *av7110, int av)
{
- DEB_EE(("av7110: %p\n", av7110));
+ dprintk(2, "av7110:%p, \n", av7110);

if (!(av7110->playing & av) && !(av7110->rec_mode & av))
return;
@@ -243,8 +238,6 @@
u32 sync;
u16 blen;

- DEB_EE(("dvb_ring_buffer_t: %p\n", buf));
-
if (!dlen) {
wake_up(&buf->queue);
return -1;
@@ -275,8 +268,8 @@

dvb_ringbuffer_read(buf, dest, (size_t) blen, 0);

- DEB_S(("pread=0x%08lx, pwrite=0x%08lx\n",
- (unsigned long) buf->pread, (unsigned long) buf->pwrite));
+ dprintk(2, "pread=0x%08lx, pwrite=0x%08lx\n",
+ (unsigned long) buf->pread, (unsigned long) buf->pwrite);
wake_up(&buf->queue);
return blen;
}
@@ -286,7 +278,7 @@
{
int err, vol, val, balance = 0;

- DEB_EE(("av7110: %p\n", av7110));
+ dprintk(2, "av7110:%p, \n", av7110);

av7110->mixer.volume_left = volleft;
av7110->mixer.volume_right = volright;
@@ -325,7 +317,7 @@

void av7110_set_vidmode(struct av7110 *av7110, int mode)
{
- DEB_EE(("av7110: %p\n", av7110));
+ dprintk(2, "av7110:%p, \n", av7110);

av7110_fw_cmd(av7110, COMTYPE_ENCODER, LoadVidCode, 1, mode);

@@ -353,7 +345,7 @@
int sw;
u8 *p;

- DEB_EE(("av7110: %p\n", av7110));
+ dprintk(2, "av7110:%p, \n", av7110);

if (av7110->sinfo)
return;
@@ -366,7 +358,7 @@
vsize = ((p[1] &0x0F) << 8) | (p[2]);
sw = (p[3] & 0x0F);
av7110_set_vidmode(av7110, sw2mode[sw]);
- DEB_S(("dvb: playback %dx%d fr=%d\n", hsize, vsize, sw));
+ dprintk(2, "playback %dx%d fr=%d\n", hsize, vsize, sw);
av7110->sinfo = 1;
break;
}
@@ -403,7 +395,7 @@
static void play_video_cb(u8 *buf, int count, void *priv)
{
struct av7110 *av7110 = (struct av7110 *) priv;
- DEB_EE(("av7110: %p\n", av7110));
+ dprintk(2, "av7110:%p, \n", av7110);

if ((buf[3] & 0xe0) == 0xe0) {
get_video_format(av7110, buf, count);
@@ -415,7 +407,7 @@
static void play_audio_cb(u8 *buf, int count, void *priv)
{
struct av7110 *av7110 = (struct av7110 *) priv;
- DEB_EE(("av7110: %p\n", av7110));
+ dprintk(2, "av7110:%p, \n", av7110);

aux_ring_buffer_write(&av7110->aout, buf, count);
}
@@ -427,7 +419,7 @@
unsigned long count, int nonblock, int type)
{
unsigned long todo = count, n;
- DEB_EE(("av7110: %p\n", av7110));
+ dprintk(2, "av7110:%p, \n", av7110);

if (!av7110->kbuf[type])
return -ENOBUFS;
@@ -460,7 +452,7 @@
unsigned long count, int nonblock, int type)
{
unsigned long todo = count, n;
- DEB_EE(("av7110: %p\n", av7110));
+ dprintk(2, "av7110:%p, \n", av7110);

if (!av7110->kbuf[type])
return -ENOBUFS;
@@ -490,7 +482,7 @@
unsigned long count, int nonblock, int type)
{
unsigned long todo = count, n;
- DEB_EE(("av7110: %p\n", av7110));
+ dprintk(2, "av7110:%p, \n", av7110);

if (!av7110->kbuf[type])
return -ENOBUFS;
@@ -769,7 +761,7 @@
struct av7110 *av7110 = (struct av7110 *) demux->priv;
struct ipack *ipack = &av7110->ipack[feed->pes_type];

- DEB_EE(("av7110: %p\n", av7110));
+ dprintk(2, "av7110:%p, \n", av7110);

switch (feed->pes_type) {
case 0:
@@ -810,8 +802,6 @@
struct dvb_video_events *events = &av7110->video_events;
int wp;

- DEB_D(("\n"));
-
spin_lock_bh(&events->lock);

wp = (events->eventw + 1) % MAX_VIDEO_EVENT;
@@ -834,8 +824,6 @@
{
struct dvb_video_events *events = &av7110->video_events;

- DEB_D(("\n"));
-
if (events->overflow) {
events->overflow = 0;
return -EOVERFLOW;
@@ -874,7 +862,7 @@
struct av7110 *av7110 = (struct av7110 *) dvbdev->priv;
unsigned int mask = 0;

- DEB_EE(("av7110: %p\n", av7110));
+ dprintk(2, "av7110:%p, \n", av7110);

if ((file->f_flags & O_ACCMODE) != O_RDONLY)
poll_wait(file, &av7110->avout.queue, wait);
@@ -901,7 +889,7 @@
struct dvb_device *dvbdev = (struct dvb_device *) file->private_data;
struct av7110 *av7110 = (struct av7110 *) dvbdev->priv;

- DEB_EE(("av7110: %p\n", av7110));
+ dprintk(2, "av7110:%p, \n", av7110);

if ((file->f_flags & O_ACCMODE) == O_RDONLY)
return -EPERM;
@@ -918,7 +906,7 @@
struct av7110 *av7110 = (struct av7110 *) dvbdev->priv;
unsigned int mask = 0;

- DEB_EE(("av7110: %p\n", av7110));
+ dprintk(2, "av7110:%p, \n", av7110);

poll_wait(file, &av7110->aout.queue, wait);

@@ -937,7 +925,7 @@
struct dvb_device *dvbdev = (struct dvb_device *) file->private_data;
struct av7110 *av7110 = (struct av7110 *) dvbdev->priv;

- DEB_EE(("av7110: %p\n", av7110));
+ dprintk(2, "av7110:%p, \n", av7110);

if (av7110->audiostate.stream_source != AUDIO_SOURCE_MEMORY) {
printk(KERN_ERR "not audio source memory\n");
@@ -954,7 +942,7 @@
{
int i, n;

- DEB_EE(("av7110: %p\n", av7110));
+ dprintk(2, "av7110:%p, \n", av7110);

if (!(av7110->playing & RP_VIDEO)) {
if (av7110_av_start_play(av7110, RP_VIDEO) < 0)
@@ -984,7 +972,7 @@
unsigned long arg = (unsigned long) parg;
int ret = 0;

- DEB_EE(("av7110: %p\n", av7110));
+ dprintk(2, "av7110:%p, \n", av7110);

if ((file->f_flags & O_ACCMODE) == O_RDONLY) {
if ( cmd != VIDEO_GET_STATUS && cmd != VIDEO_GET_EVENT &&
@@ -1180,7 +1168,7 @@
unsigned long arg = (unsigned long) parg;
int ret = 0;

- DEB_EE(("av7110: %p\n", av7110));
+ dprintk(2, "av7110:%p, \n", av7110);

if (((file->f_flags & O_ACCMODE) == O_RDONLY) &&
(cmd != AUDIO_GET_STATUS))
@@ -1296,7 +1284,7 @@
struct av7110 *av7110 = (struct av7110 *) dvbdev->priv;
int err;

- DEB_EE(("av7110: %p\n", av7110));
+ dprintk(2, "av7110:%p, \n", av7110);

if ((err = dvb_generic_open(inode, file)) < 0)
return err;
@@ -1320,7 +1308,7 @@
struct dvb_device *dvbdev = (struct dvb_device *) file->private_data;
struct av7110 *av7110 = (struct av7110 *) dvbdev->priv;

- DEB_EE(("av7110: %p\n", av7110));
+ dprintk(2, "av7110:%p, \n", av7110);

if ((file->f_flags & O_ACCMODE) != O_RDONLY) {
av7110_av_stop(av7110, RP_VIDEO);
@@ -1335,7 +1323,7 @@
struct av7110 *av7110 = (struct av7110 *) dvbdev->priv;
int err=dvb_generic_open(inode, file);

- DEB_EE(("av7110: %p\n", av7110));
+ dprintk(2, "av7110:%p, \n", av7110);

if (err < 0)
return err;
@@ -1349,7 +1337,7 @@
struct dvb_device *dvbdev = (struct dvb_device *) file->private_data;
struct av7110 *av7110 = (struct av7110 *) dvbdev->priv;

- DEB_EE(("av7110: %p\n", av7110));
+ dprintk(2, "av7110:%p, \n", av7110);

av7110_av_stop(av7110, RP_AUDIO);
return dvb_generic_release(inode, file);
diff -uraNwB linux-2.6.10-rc1/drivers/media/dvb/ttpci/av7110_ca.c linux-2.6.10-rc1-patched/drivers/media/dvb/ttpci/av7110_ca.c
--- linux-2.6.10-rc1/drivers/media/dvb/ttpci/av7110_ca.c 2004-10-25 14:07:52.000000000 +0200
+++ linux-2.6.10-rc1-patched/drivers/media/dvb/ttpci/av7110_ca.c 2004-10-25 14:14:44.000000000 +0200
@@ -44,7 +44,7 @@

void CI_handle(struct av7110 *av7110, u8 *data, u16 len)
{
- DEB_EE(("av7110: %p\n", av7110));
+ dprintk(8, "av7110:%p\n",av7110);

if (len < 3)
return;
@@ -207,7 +207,7 @@
struct av7110 *av7110 = (struct av7110 *) dvbdev->priv;
int err = dvb_generic_open(inode, file);

- DEB_EE(("av7110: %p\n", av7110));
+ dprintk(8, "av7110:%p\n",av7110);

if (err < 0)
return err;
@@ -223,13 +223,16 @@
struct dvb_ringbuffer *wbuf = &av7110->ci_wbuffer;
unsigned int mask = 0;

- DEB_EE(("av7110: %p\n", av7110));
+ dprintk(8, "av7110:%p\n",av7110);

poll_wait(file, &rbuf->queue, wait);
+ poll_wait(file, &wbuf->queue, wait);
+
if (!dvb_ringbuffer_empty(rbuf))
- mask |= POLLIN;
- if (dvb_ringbuffer_avail(wbuf) > 1024)
- mask |= POLLOUT;
+ mask |= (POLLIN | POLLRDNORM);
+
+ if (dvb_ringbuffer_free(wbuf) > 1024)
+ mask |= (POLLOUT | POLLWRNORM);

return mask;
}
@@ -241,7 +244,7 @@
struct av7110 *av7110 = (struct av7110 *) dvbdev->priv;
unsigned long arg = (unsigned long) parg;

- DEB_EE(("av7110: %p\n", av7110));
+ dprintk(8, "av7110:%p\n",av7110);

switch (cmd) {
case CA_RESET:
@@ -318,7 +321,7 @@
struct dvb_device *dvbdev = (struct dvb_device *) file->private_data;
struct av7110 *av7110 = (struct av7110 *) dvbdev->priv;

- DEB_EE(("av7110: %p\n", av7110));
+ dprintk(8, "av7110:%p\n",av7110);
return ci_ll_write(&av7110->ci_wbuffer, file, buf, count, ppos);
}

@@ -328,7 +331,7 @@
struct dvb_device *dvbdev = (struct dvb_device *) file->private_data;
struct av7110 *av7110 = (struct av7110 *) dvbdev->priv;

- DEB_EE(("av7110: %p\n", av7110));
+ dprintk(8, "av7110:%p\n",av7110);
return ci_ll_read(&av7110->ci_rbuffer, file, buf, count, ppos);
}

diff -uraNwB linux-2.6.10-rc1/drivers/media/dvb/ttpci/av7110_hw.c linux-2.6.10-rc1-patched/drivers/media/dvb/ttpci/av7110_hw.c
--- linux-2.6.10-rc1/drivers/media/dvb/ttpci/av7110_hw.c 2004-10-25 14:07:50.000000000 +0200
+++ linux-2.6.10-rc1-patched/drivers/media/dvb/ttpci/av7110_hw.c 2004-10-25 14:14:44.000000000 +0200
@@ -110,7 +110,7 @@
IER_ENABLE(av7110->dev, MASK_03);

av7110->arm_ready = 1;
- printk("av7110: ARM RESET\n");
+ dprintk(1, "reset ARM\n");
}


@@ -118,7 +118,7 @@
{
int k;

- DEB_EE(("av7110: %p\n", av7110));
+ dprintk(4, "%p\n", av7110);

for (k = 0; k < 100; k++) {
if (irdebi(av7110, DEBINOSWAP, adr, 0, 2) == state)
@@ -134,7 +134,7 @@
int blocks, rest;
u32 base, bootblock = BOOT_BLOCK;

- DEB_EE(("av7110: %p\n", av7110));
+ dprintk(4, "%p\n", av7110);

blocks = len / BOOT_MAX_SIZE;
rest = len % BOOT_MAX_SIZE;
@@ -143,7 +143,7 @@
for (i = 0; i < blocks; i++) {
if (waitdebi(av7110, BOOT_STATE, BOOTSTATE_BUFFER_EMPTY) < 0)
return -1;
- DEB_D(("Writing DRAM block %d\n", i));
+ dprintk(4, "writing DRAM block %d\n", i);
mwdebi(av7110, DEBISWAB, bootblock,
((char*)data) + i * BOOT_MAX_SIZE, BOOT_MAX_SIZE);
bootblock ^= 0x1400;
@@ -206,7 +206,7 @@
u32 ret;
int i;

- DEB_EE(("av7110: %p\n", av7110));
+ dprintk(4, "%p\n", av7110);

saa7146_setgpio(dev, RESET_LINE, SAA7146_GPIO_OUTLO);

@@ -222,17 +222,17 @@
/* test DEBI */
iwdebi(av7110, DEBISWAP, DPRAM_BASE, 0x76543210, 4);
if ((ret=irdebi(av7110, DEBINOSWAP, DPRAM_BASE, 0, 4)) != 0x10325476) {
- printk(KERN_ERR "dvb: debi test in av7110_bootarm() failed: "
- "%08x != %08x (check your BIOS hotplug settings)\n",
+ printk(KERN_ERR "dvb-ttpci: debi test in av7110_bootarm() failed: "
+ "%08x != %08x (check your BIOS 'Plug&Play OS' settings)\n",
ret, 0x10325476);
return -1;
}
for (i = 0; i < 8192; i += 4)
iwdebi(av7110, DEBISWAP, DPRAM_BASE + i, 0x00, 4);
- DEB_D(("av7110_bootarm: debi test OK\n"));
+ dprintk(2, "debi test OK\n");

/* boot */
- DEB_D(("av7110_bootarm: load boot code\n"));
+ dprintk(1, "load boot code\n");
saa7146_setgpio(dev, ARM_IRQ_LINE, SAA7146_GPIO_IRQLO);
//saa7146_setgpio(dev, DEBI_DONE_LINE, SAA7146_GPIO_INPUT);
//saa7146_setgpio(dev, 3, SAA7146_GPIO_INPUT);
@@ -241,25 +241,25 @@
iwdebi(av7110, DEBINOSWAP, BOOT_STATE, BOOTSTATE_BUFFER_FULL, 2);

if (saa7146_wait_for_debi_done(av7110->dev)) {
- printk(KERN_ERR "dvb: av7110_bootarm(): "
+ printk(KERN_ERR "dvb-ttpci: av7110_bootarm(): "
"saa7146_wait_for_debi_done() timed out\n");
return -1;
}
saa7146_setgpio(dev, RESET_LINE, SAA7146_GPIO_OUTHI);
mdelay(1);

- DEB_D(("av7110_bootarm: load dram code\n"));
+ dprintk(1, "load dram code\n");
if (load_dram(av7110, (u32 *)av7110->bin_root, av7110->size_root) < 0)
return -1;

saa7146_setgpio(dev, RESET_LINE, SAA7146_GPIO_OUTLO);
mdelay(1);

- DEB_D(("av7110_bootarm: load dpram code\n"));
+ dprintk(1, "load dpram code\n");
mwdebi(av7110, DEBISWAB, DPRAM_BASE, av7110->bin_dpram, av7110->size_dpram);

if (saa7146_wait_for_debi_done(av7110->dev)) {
- printk(KERN_ERR "dvb: av7110_bootarm(): "
+ printk(KERN_ERR "dvb-ttpci: av7110_bootarm(): "
"saa7146_wait_for_debi_done() timed out after loading DRAM\n");
return -1;
}
@@ -289,10 +289,10 @@
u32 stat;
#endif

-// DEB_EE(("av7110: %p\n", av7110));
+// dprintk(4, "%p\n", av7110);

if (!av7110->arm_ready) {
- DEB_D(("arm not ready.\n"));
+ dprintk(1, "arm not ready.\n");
return -1;
}

@@ -300,7 +300,7 @@
while (rdebi(av7110, DEBINOSWAP, COMMAND, 0, 2 )) {
msleep(1);
if (time_after(jiffies, start + ARM_WAIT_FREE)) {
- printk(KERN_ERR "%s: timeout waiting for COMMAND idle\n", __FUNCTION__);
+ printk(KERN_ERR "dvb-ttpci: %s(): timeout waiting for COMMAND idle\n", __FUNCTION__);
return -1;
}
}
@@ -310,7 +310,7 @@
while (rdebi(av7110, DEBINOSWAP, HANDSHAKE_REG, 0, 2 )) {
msleep(1);
if (time_after(jiffies, start + ARM_WAIT_SHAKE)) {
- printk(KERN_ERR "%s: timeout waiting for HANDSHAKE_REG\n", __FUNCTION__);
+ printk(KERN_ERR "dvb-ttpci: %s(): timeout waiting for HANDSHAKE_REG\n", __FUNCTION__);
return -1;
}
}
@@ -320,7 +320,7 @@
while (rdebi(av7110, DEBINOSWAP, MSGSTATE, 0, 2) & OSDQFull) {
msleep(1);
if (time_after(jiffies, start + ARM_WAIT_OSD)) {
- printk(KERN_ERR "%s: timeout waiting for !OSDQFull\n", __FUNCTION__);
+ printk(KERN_ERR "dvb-ttpci: %s(): timeout waiting for !OSDQFull\n", __FUNCTION__);
return -1;
}
}
@@ -339,7 +339,7 @@
while (rdebi(av7110, DEBINOSWAP, COMMAND, 0, 2 )) {
msleep(1);
if (time_after(jiffies, start + ARM_WAIT_FREE)) {
- printk(KERN_ERR "%s: timeout waiting for COMMAND to complete\n",
+ printk(KERN_ERR "dvb-ttpci: %s(): timeout waiting for COMMAND to complete\n",
__FUNCTION__);
return -1;
}
@@ -347,11 +347,11 @@

stat = rdebi(av7110, DEBINOSWAP, MSGSTATE, 0, 2);
if (stat & GPMQOver) {
- printk(KERN_ERR "%s: GPMQOver\n", __FUNCTION__);
+ printk(KERN_ERR "dvb-ttpci: %s(): GPMQOver\n", __FUNCTION__);
return -1;
}
else if (stat & OSDQOver) {
- printk(KERN_ERR "%s: OSDQOver\n", __FUNCTION__);
+ printk(KERN_ERR "dvb-ttpci: %s(): OSDQOver\n", __FUNCTION__);
return -1;
}
#endif
@@ -363,10 +363,10 @@
{
int ret;

-// DEB_EE(("av7110: %p\n", av7110));
+// dprintk(4, "%p\n", av7110);

if (!av7110->arm_ready) {
- DEB_D(("arm not ready.\n"));
+ dprintk(1, "arm not ready.\n");
return -1;
}
if (down_interruptible(&av7110->dcomlock))
@@ -375,7 +375,7 @@
ret = __av7110_send_fw_cmd(av7110, buf, length);
up(&av7110->dcomlock);
if (ret)
- printk("av7110_send_fw_cmd error\n");
+ printk("dvb-ttpci: %s(): av7110_send_fw_cmd error\n", __FUNCTION__);
return ret;
}

@@ -385,7 +385,7 @@
u16 buf[num + 2];
int i, ret;

-// DEB_EE(("av7110: %p\n",av7110));
+// dprintk(4, "%p\n", av7110);

buf[0] = ((type << 8) | com);
buf[1] = num;
@@ -399,7 +399,7 @@

ret = av7110_send_fw_cmd(av7110, buf, num + 2);
if (ret)
- printk("av7110_fw_cmd error\n");
+ printk("dvb-ttpci: av7110_fw_cmd error\n");
return ret;
}

@@ -409,7 +409,7 @@
u16 cmd[18] = { ((COMTYPE_COMMON_IF << 8) + subcom),
16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };

- DEB_EE(("av7110: %p\n", av7110));
+ dprintk(4, "%p\n", av7110);

for(i = 0; i < len && i < 32; i++)
{
@@ -421,7 +421,7 @@

ret = av7110_send_fw_cmd(av7110, cmd, 18);
if (ret)
- printk("av7110_send_ci_cmd error\n");
+ printk("dvb-ttpci: av7110_send_ci_cmd error\n");
return ret;
}

@@ -435,10 +435,10 @@
u32 stat;
#endif

- DEB_EE(("av7110: %p\n", av7110));
+ dprintk(4, "%p\n", av7110);

if (!av7110->arm_ready) {
- DEB_D(("arm not ready.\n"));
+ dprintk(1, "arm not ready.\n");
return -1;
}

@@ -447,7 +447,7 @@

if ((err = __av7110_send_fw_cmd(av7110, request_buf, request_buf_len)) < 0) {
up(&av7110->dcomlock);
- printk("av7110_fw_request error\n");
+ printk("dvb-ttpci: av7110_fw_request error\n");
return err;
}

@@ -457,7 +457,7 @@
msleep(1);
#endif
if (time_after(jiffies, start + ARM_WAIT_FREE)) {
- printk("%s: timeout waiting for COMMAND to complete\n", __FUNCTION__);
+ printk(KERN_ERR "%s: timeout waiting for COMMAND to complete\n", __FUNCTION__);
up(&av7110->dcomlock);
return -1;
}
@@ -501,7 +501,7 @@
int ret;
ret = av7110_fw_request(av7110, &tag, 0, buf, length);
if (ret)
- printk("av7110_fw_query error\n");
+ printk("dvb-ttpci: av7110_fw_query error\n");
return ret;
}

@@ -516,10 +516,10 @@
u16 buf[20];
u16 tag = ((COMTYPE_REQUEST << 8) + ReqVersion);

- DEB_EE(("av7110: %p\n", av7110));
+ dprintk(4, "%p\n", av7110);

if (av7110_fw_query(av7110, tag, buf, 16)) {
- printk("DVB: AV7110-%d: ERROR: Failed to boot firmware\n",
+ printk("dvb-ttpci: failed to boot firmware @ card %d\n",
av7110->dvb_adapter->num);
return -EIO;
}
@@ -530,17 +530,17 @@
av7110->arm_app = (buf[6] << 16) + buf[7];
av7110->avtype = (buf[8] << 16) + buf[9];

- printk("DVB: AV711%d(%d) - firm %08x, rtsl %08x, vid %08x, app %08x\n",
- av7110->avtype, av7110->dvb_adapter->num, av7110->arm_fw,
+ printk("dvb-ttpci: info @ card %d: firm %08x, rtsl %08x, vid %08x, app %08x\n",
+ av7110->dvb_adapter->num, av7110->arm_fw,
av7110->arm_rtsl, av7110->arm_vid, av7110->arm_app);

/* print firmware capabilities */
if (FW_CI_LL_SUPPORT(av7110->arm_app))
- printk("DVB: AV711%d(%d) - firmware supports CI link layer interface\n",
- av7110->avtype, av7110->dvb_adapter->num);
+ printk("dvb-ttpci: firmware @ card %d supports CI link layer interface\n",
+ av7110->dvb_adapter->num);
else
- printk("DVB: AV711%d(%d) - no firmware support for CI link layer interface\n",
- av7110->avtype, av7110->dvb_adapter->num);
+ printk("dvb-ttpci: no firmware support for CI link layer interface @ card %d\n",
+ av7110->dvb_adapter->num);

return 0;
}
@@ -552,7 +552,7 @@
u16 buf[18] = { ((COMTYPE_AUDIODAC << 8) + SendDiSEqC),
16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };

- DEB_EE(("av7110: %p\n", av7110));
+ dprintk(4, "%p\n", av7110);

if (len > 10)
len = 10;
@@ -569,7 +569,7 @@
buf[i + 4] = msg[i];

if (av7110_send_fw_cmd(av7110, buf, 18))
- printk("av7110_diseqc_send error\n");
+ printk("dvb-ttpci: av7110_diseqc_send error\n");

return 0;
}
@@ -628,7 +628,7 @@
while (rdebi(av7110, DEBINOSWAP, BUFF1_BASE, 0, 2)) {
msleep(1);
if (time_after(jiffies, start + ARM_WAIT_OSD)) {
- printk(KERN_ERR "%s: timeout waiting for BUFF1_BASE == 0\n",
+ printk(KERN_ERR "dvb-ttpci: %s(): timeout waiting for BUFF1_BASE == 0\n",
__FUNCTION__);
up(&av7110->dcomlock);
return -1;
@@ -652,7 +652,7 @@
while (rdebi(av7110, DEBINOSWAP, BUFF1_BASE, 0, 2)) {
msleep(1);
if (time_after(jiffies, start + ARM_WAIT_OSD)) {
- printk(KERN_ERR "%s: timeout waiting for BUFF1_BASE == 0\n",
+ printk(KERN_ERR "dvb-ttpci: %s: timeout waiting for BUFF1_BASE == 0\n",
__FUNCTION__);
up(&av7110->dcomlock);
return -1;
@@ -663,7 +663,7 @@
while (rdebi(av7110, DEBINOSWAP, HANDSHAKE_REG, 0, 2)) {
msleep(1);
if (time_after(jiffies, start + ARM_WAIT_SHAKE)) {
- printk(KERN_ERR "%s: timeout waiting for HANDSHAKE_REG\n",
+ printk(KERN_ERR "dvb-ttpci: %s: timeout waiting for HANDSHAKE_REG\n",
__FUNCTION__);
up(&av7110->dcomlock);
return -1;
@@ -678,7 +678,7 @@
ret = __av7110_send_fw_cmd(av7110, cbuf, 5);
up(&av7110->dcomlock);
if (ret)
- printk("WriteText error\n");
+ printk("dvb-ttpci: WriteText error\n");
return ret;
}

@@ -741,7 +741,7 @@
u8 c;
int ret;

- DEB_EE(("av7110: %p\n", av7110));
+ dprintk(4, "%p\n", av7110);

ret = wait_event_interruptible_timeout(av7110->bmpq, av7110->bmp_state != BMP_LOADING, HZ);
if (ret == -ERESTARTSYS || ret == 0) {
@@ -794,7 +794,7 @@
{
int ret;

- DEB_EE(("av7110: %p\n", av7110));
+ dprintk(4, "%p\n", av7110);

BUG_ON (av7110->bmp_state == BMP_NONE);

@@ -812,7 +812,7 @@

static inline int ReleaseBitmap(struct av7110 *av7110)
{
- DEB_EE(("av7110: %p\n",av7110));
+ dprintk(4, "%p\n", av7110);

if (av7110->bmp_state != BMP_LOADED)
return -1;
diff -uraNwB linux-2.6.10-rc1/drivers/media/dvb/ttpci/av7110_ir.c linux-2.6.10-rc1-patched/drivers/media/dvb/ttpci/av7110_ir.c
--- linux-2.6.10-rc1/drivers/media/dvb/ttpci/av7110_ir.c 2004-10-25 14:07:52.000000000 +0200
+++ linux-2.6.10-rc1-patched/drivers/media/dvb/ttpci/av7110_ir.c 2004-10-25 14:14:44.000000000 +0200
@@ -4,18 +4,13 @@
#include <linux/moduleparam.h>
#include <linux/input.h>
#include <linux/proc_fs.h>
-#include <linux/bitops.h>
+#include <asm/bitops.h>

#include "av7110.h"

#define UP_TIMEOUT (HZ/4)

-static int av7110_ir_debug;
-
-module_param_named(debug_ir, av7110_ir_debug, int, 0644);
-MODULE_PARM_DESC(av7110_ir_debug, "Turn on/off IR debugging (default:off).");
-
-#define dprintk(x...) do { if (av7110_ir_debug) printk (x); } while (0)
+/* enable ir debugging by or'ing av7110_debug with 16 */

static struct input_dev input_dev;

@@ -78,7 +73,7 @@

keycode = key_map[data];

- dprintk ("#########%08x######### addr %i data 0x%02x (keycode %i)\n",
+ dprintk(16, "#########%08x######### addr %i data 0x%02x (keycode %i)\n",
ircom, addr, data, keycode);

/* check device address (if selected) */
diff -uraNwB linux-2.6.10-rc1/drivers/media/dvb/ttpci/av7110_v4l.c linux-2.6.10-rc1-patched/drivers/media/dvb/ttpci/av7110_v4l.c
--- linux-2.6.10-rc1/drivers/media/dvb/ttpci/av7110_v4l.c 2004-10-25 14:07:51.000000000 +0200
+++ linux-2.6.10-rc1-patched/drivers/media/dvb/ttpci/av7110_v4l.c 2004-10-25 14:14:44.000000000 +0200
@@ -45,8 +45,8 @@
struct i2c_msg msgs = { .flags = 0, .addr = 0x40, .len = 5, .buf = msg };

if (i2c_transfer(&av7110->i2c_adap, &msgs, 1) != 1) {
- printk("av7110(%d): %s(%u = %u) failed\n",
- av7110->dvb_adapter->num, __FUNCTION__, reg, val);
+ dprintk(1, "dvb-ttpci: failed @ card %d, %u = %u\n",
+ av7110->dvb_adapter->num, reg, val);
return -EIO;
}
return 0;
@@ -62,8 +62,8 @@
};

if (i2c_transfer(&av7110->i2c_adap, &msgs[0], 2) != 2) {
- printk("av7110(%d): %s(%u) failed\n",
- av7110->dvb_adapter->num, __FUNCTION__, reg);
+ dprintk(1, "dvb-ttpci: failed @ card %d, %u\n",
+ av7110->dvb_adapter->num, reg);
return -EIO;
}
*val = (msg2[0] << 8) | msg2[1];
@@ -99,7 +97,7 @@
u8 buf[] = { 0x00, reg, data };
struct i2c_msg msg = { .addr = addr, .flags = 0, .buf = buf, .len = 3 };

- DEB_EE(("av7710: dev: %p\n", dev));
+ dprintk(4, "dev: %p\n", dev);

if (1 != saa7146_i2c_transfer(dev, &msg, 1, 1))
return -1;
@@ -110,7 +108,7 @@
{
struct i2c_msg msg = { .addr = addr, .flags = 0, .buf = data, .len = 4 };

- DEB_EE(("av7710: dev: %p\n", dev));
+ dprintk(4, "dev: %p\n", dev);

if (1 != saa7146_i2c_transfer(dev, &msg, 1, 1))
return -1;
@@ -128,7 +126,7 @@
u8 config;
u8 buf[4];

- DEB_EE(("av7710: freq: 0x%08x\n", freq));
+ dprintk(4, "freq: 0x%08x\n", freq);

/* magic number: 614. tuning with the frequency given by v4l2
is always off by 614*62.5 = 38375 kHz...*/
@@ -171,13 +169,13 @@
u8 band = 0;
int source, sync, err;

- DEB_EE(("av7110: %p\n", av7110));
+ dprintk(4, "%p\n", av7110);

if ((vv->video_status & STATUS_OVERLAY) != 0) {
vv->ov_suspend = vv->video_fh;
err = saa7146_stop_preview(vv->video_fh); /* side effect: video_status is now 0, video_fh is NULL */
if (err != 0) {
- DEB_D(("warning: suspending video failed\n"));
+ dprintk(2, "suspending video failed\n");
vv->ov_suspend = NULL;
}
}
@@ -188,7 +186,7 @@
source = SAA7146_HPS_SOURCE_PORT_B;
sync = SAA7146_HPS_SYNC_PORT_B;
memcpy(standard, analog_standard, sizeof(struct saa7146_standard) * 2);
- printk("av7110: switching to analog TV\n");
+ dprintk(1, "switching to analog TV\n");
msp_writereg(av7110, MSP_WR_DSP, 0x0008, 0x0000); // loudspeaker source
msp_writereg(av7110, MSP_WR_DSP, 0x0009, 0x0000); // headphone source
msp_writereg(av7110, MSP_WR_DSP, 0x000a, 0x0000); // SCART 1 source
@@ -201,7 +199,7 @@
source = SAA7146_HPS_SOURCE_PORT_A;
sync = SAA7146_HPS_SYNC_PORT_A;
memcpy(standard, dvb_standard, sizeof(struct saa7146_standard) * 2);
- printk("av7110: switching DVB mode\n");
+ dprintk(1, "switching DVB mode\n");
msp_writereg(av7110, MSP_WR_DSP, 0x0008, 0x0220); // loudspeaker source
msp_writereg(av7110, MSP_WR_DSP, 0x0009, 0x0220); // headphone source
msp_writereg(av7110, MSP_WR_DSP, 0x000a, 0x0220); // SCART 1 source
@@ -212,10 +210,11 @@

/* hmm, this does not do anything!? */
if (av7110_fw_cmd(av7110, COMTYPE_AUDIODAC, ADSwitch, 1, adswitch))
- printk("ADSwitch error\n");
+ dprintk(1, "ADSwitch error\n");

if (ves1820_writereg(dev, 0x0f, band))
- printk("setting band in demodulator failed.\n");
+ dprintk(1, "setting band in demodulator failed.\n");
+
saa7146_set_hps_source_and_sync(dev, source, sync);

if (vv->ov_suspend != NULL) {
@@ -230,7 +229,7 @@
{
struct saa7146_dev *dev = fh->dev;
struct av7110 *av7110 = (struct av7110*) dev->ext_priv;
- DEB_EE(("saa7146_dev: %p\n", dev));
+ dprintk(4, "saa7146_dev: %p\n", dev);

switch (cmd) {
case VIDIOC_G_TUNER:
@@ -239,7 +238,7 @@
u16 stereo_det;
s8 stereo;

- DEB_EE(("VIDIOC_G_TUNER: %d\n", t->index));
+ dprintk(2, "VIDIOC_G_TUNER: %d\n", t->index);

if (!av7110->has_analog_tuner || t->index != 0)
return -EINVAL;
@@ -258,10 +257,10 @@

// FIXME: standard / stereo detection is still broken
msp_readreg(av7110, MSP_RD_DEM, 0x007e, &stereo_det);
-printk("VIDIOC_G_TUNER: msp3400 TV standard detection: 0x%04x\n", stereo_det);
+ dprintk(1, "VIDIOC_G_TUNER: msp3400 TV standard detection: 0x%04x\n", stereo_det);

msp_readreg(av7110, MSP_RD_DSP, 0x0018, &stereo_det);
- printk("VIDIOC_G_TUNER: msp3400 stereo detection: 0x%04x\n", stereo_det);
+ dprintk(1, "VIDIOC_G_TUNER: msp3400 stereo detection: 0x%04x\n", stereo_det);
stereo = (s8)(stereo_det >> 8);
if (stereo > 0x10) {
/* stereo */
@@ -282,29 +281,29 @@
{
struct v4l2_tuner *t = arg;
u16 fm_matrix, src;
- DEB_EE(("VIDIOC_S_TUNER: %d\n", t->index));
+ dprintk(2, "VIDIOC_S_TUNER: %d\n", t->index);

if (!av7110->has_analog_tuner || av7110->current_input != 1)
return -EINVAL;

switch (t->audmode) {
case V4L2_TUNER_MODE_STEREO:
- DEB_D(("VIDIOC_S_TUNER: V4L2_TUNER_MODE_STEREO\n"));
+ dprintk(2, "VIDIOC_S_TUNER: V4L2_TUNER_MODE_STEREO\n");
fm_matrix = 0x3001; // stereo
src = 0x0020;
break;
case V4L2_TUNER_MODE_LANG1:
- DEB_D(("VIDIOC_S_TUNER: V4L2_TUNER_MODE_LANG1\n"));
+ dprintk(2, "VIDIOC_S_TUNER: V4L2_TUNER_MODE_LANG1\n");
fm_matrix = 0x3000; // mono
src = 0x0000;
break;
case V4L2_TUNER_MODE_LANG2:
- DEB_D(("VIDIOC_S_TUNER: V4L2_TUNER_MODE_LANG2\n"));
+ dprintk(2, "VIDIOC_S_TUNER: V4L2_TUNER_MODE_LANG2\n");
fm_matrix = 0x3000; // mono
src = 0x0010;
break;
default: /* case V4L2_TUNER_MODE_MONO: {*/
- DEB_D(("VIDIOC_S_TUNER: TDA9840_SET_MONO\n"));
+ dprintk(2, "VIDIOC_S_TUNER: TDA9840_SET_MONO\n");
fm_matrix = 0x3000; // mono
src = 0x0030;
break;
@@ -319,7 +318,7 @@
{
struct v4l2_frequency *f = arg;

- DEB_EE(("VIDIOC_G_FREQ: freq:0x%08x.\n", f->frequency));
+ dprintk(2, "VIDIOC_G_FREQ: freq:0x%08x.\n", f->frequency);

if (!av7110->has_analog_tuner || av7110->current_input != 1)
return -EINVAL;
@@ -333,7 +332,7 @@
{
struct v4l2_frequency *f = arg;

- DEB_EE(("VIDIOC_S_FREQUENCY: freq:0x%08x.\n", f->frequency));
+ dprintk(2, "VIDIOC_S_FREQUENCY: freq:0x%08x.\n", f->frequency);

if (!av7110->has_analog_tuner || av7110->current_input != 1)
return -EINVAL;
@@ -358,7 +357,7 @@
{
struct v4l2_input *i = arg;

- DEB_EE(("VIDIOC_ENUMINPUT: %d\n", i->index));
+ dprintk(2, "VIDIOC_ENUMINPUT: %d\n", i->index);

if (av7110->has_analog_tuner ) {
if (i->index < 0 || i->index >= 2)
@@ -376,14 +375,14 @@
{
int *input = (int *)arg;
*input = av7110->current_input;
- DEB_EE(("VIDIOC_G_INPUT: %d\n", *input));
+ dprintk(2, "VIDIOC_G_INPUT: %d\n", *input);
return 0;
}
case VIDIOC_S_INPUT:
{
int input = *(int *)arg;

- DEB_EE(("VIDIOC_S_INPUT: %d\n", input));
+ dprintk(2, "VIDIOC_S_INPUT: %d\n", input);

if (!av7110->has_analog_tuner )
return 0;
@@ -399,7 +398,7 @@
{
struct v4l2_audio *a = arg;

- DEB_EE(("VIDIOC_G_AUDIO: %d\n", a->index));
+ dprintk(2, "VIDIOC_G_AUDIO: %d\n", a->index);
if (a->index != 0)
return -EINVAL;
memcpy(a, &msp3400_v4l2_audio, sizeof(struct v4l2_audio));
@@ -408,7 +407,7 @@
case VIDIOC_S_AUDIO:
{
struct v4l2_audio *a = arg;
- DEB_EE(("VIDIOC_S_AUDIO: %d\n", a->index));
+ dprintk(2, "VIDIOC_S_AUDIO: %d\n", a->index);
break;
}
default:
@@ -506,13 +505,13 @@
|| i2c_writereg(av7110, 0x80, 0x0, 0) != 1)
return -ENODEV;

- printk("av7110(%d): DVB-C analog module detected, initializing MSP3400\n",
+ printk("dvb-ttpci: DVB-C analog module @ card %d detected, initializing MSP3400\n",
av7110->dvb_adapter->num);
av7110->adac_type = DVB_ADAC_MSP;
msleep(100); // the probing above resets the msp...
msp_readreg(av7110, MSP_RD_DSP, 0x001e, &version1);
msp_readreg(av7110, MSP_RD_DSP, 0x001f, &version2);
- printk("av7110(%d): MSP3400 version 0x%04x 0x%04x\n",
+ dprintk(1, "dvb-ttpci: @ card %d MSP3400 version 0x%04x 0x%04x\n",
av7110->dvb_adapter->num, version1, version2);
msp_writereg(av7110, MSP_WR_DSP, 0x0013, 0x0c00);
msp_writereg(av7110, MSP_WR_DSP, 0x0000, 0x7f00); // loudspeaker + headphone
@@ -531,8 +530,7 @@
/* init the saa7113 */
while (*i != 0xff) {
if (i2c_writereg(av7110, 0x48, i[0], i[1]) != 1) {
- printk("av7110(%d): saa7113 initialization failed",
- av7110->dvb_adapter->num);
+ dprintk(1, "saa7113 initialization failed @ card %d", av7110->dvb_adapter->num);
break;
}
i += 2;
diff -uraNwB linux-2.6.10-rc1/drivers/media/dvb/ttpci/budget-av.c linux-2.6.10-rc1-patched/drivers/media/dvb/ttpci/budget-av.c
--- linux-2.6.10-rc1/drivers/media/dvb/ttpci/budget-av.c 2004-10-25 14:07:51.000000000 +0200
+++ linux-2.6.10-rc1-patched/drivers/media/dvb/ttpci/budget-av.c 2004-10-25 14:14:44.000000000 +0200
@@ -127,19 +123,18 @@
const u8 *data = saa7113_tab;

if (i2c_writereg (&budget->i2c_adap, 0x4a, 0x01, 0x08) != 1) {
- DEB_D(("saa7113: not found on KNC card\n"));
+ dprintk(1, "saa7113 not found on KNC card\n");
return -ENODEV;
}

- INFO(("saa7113: detected and initializing\n"));
+ dprintk(1, "saa7113 detected and initializing\n");

while (*data != 0xff) {
i2c_writereg(&budget->i2c_adap, 0x4a, *data, *(data+1));
data += 2;
}

- DEB_D(("saa7113: status=%02x\n",
- i2c_readreg(&budget->i2c_adap, 0x4a, 0x1f)));
+ dprintk(1, "saa7113 status=%02x\n", i2c_readreg(&budget->i2c_adap, 0x4a, 0x1f));

return 0;
}
@@ -171,7 +164,7 @@
struct budget_av *budget_av = (struct budget_av*) dev->ext_priv;
int err;

- DEB_EE(("dev: %p\n",dev));
+ dprintk(2, "dev: %p\n", dev);

if ( 1 == budget_av->has_saa7113 ) {
saa7146_setgpio(dev, 0, SAA7146_GPIO_OUTLO);
@@ -198,7 +191,7 @@
u8 *mac;
int err;

- DEB_EE(("dev: %p\n",dev));
+ dprintk(2, "dev: %p\n", dev);

if (bi->type != BUDGET_KNC1 && bi->type != BUDGET_CIN1200) {
return -ENODEV;
@@ -299,7 +288,7 @@
{
struct v4l2_input *i = arg;

- DEB_EE(("VIDIOC_ENUMINPUT %d.\n",i->index));
+ dprintk(1, "VIDIOC_ENUMINPUT %d.\n", i->index);
if( i->index < 0 || i->index >= KNC1_INPUTS) {
return -EINVAL;
}
@@ -312,19 +301,16 @@

*input = budget_av->cur_input;

- DEB_EE(("VIDIOC_G_INPUT %d.\n",*input));
+ dprintk(1, "VIDIOC_G_INPUT %d.\n", *input);
return 0;
}
case VIDIOC_S_INPUT:
{
int input = *(int *)arg;
- DEB_EE(("VIDIOC_S_INPUT %d.\n", input));
+ dprintk(1, "VIDIOC_S_INPUT %d.\n", input);
return saa7113_setinput (budget_av, input);
}
default:
-/*
- DEB2(printk("does not handle this ioctl.\n"));
-*/
return -ENOIOCTLCMD;
}
return 0;
@@ -384,21 +367,13 @@
.irq_func = ttpci_budget_irq10_handler,
};

-
static int __init budget_av_init(void)
{
- DEB_EE((".\n"));
-
- if (saa7146_register_extension(&budget_extension))
- return -ENODEV;
-
- return 0;
+ return saa7146_register_extension(&budget_extension);
}

-
static void __exit budget_av_exit(void)
{
- DEB_EE((".\n"));
saa7146_unregister_extension(&budget_extension);
}

diff -uraNwB linux-2.6.10-rc1/drivers/media/dvb/ttpci/budget-ci.c linux-2.6.10-rc1-patched/drivers/media/dvb/ttpci/budget-ci.c
--- linux-2.6.10-rc1/drivers/media/dvb/ttpci/budget-ci.c 2004-10-25 14:07:51.000000000 +0200
+++ linux-2.6.10-rc1-patched/drivers/media/dvb/ttpci/budget-ci.c 2004-10-25 14:14:44.000000000 +0200
@@ -500,7 +491,7 @@
{
struct budget_ci *budget_ci = (struct budget_ci*) dev->ext_priv;

- DEB_EE(("dev: %p, budget_ci: %p\n", dev, budget_ci));
+ dprintk(8, "dev: %p, budget_ci: %p\n", dev, budget_ci);

if (*isr & MASK_06)
tasklet_schedule (&budget_ci->msp430_irq_tasklet);
@@ -523,7 +512,7 @@
if (!(budget_ci = kmalloc (sizeof(struct budget_ci), GFP_KERNEL)))
return -ENOMEM;

- DEB_EE(("budget_ci: %p\n", budget_ci));
+ dprintk(2, "budget_ci: %p\n", budget_ci);

spin_lock_init(&budget_ci->debilock);
budget_ci->budget.ci_present = 0;
@@ -606,10 +590,8 @@
return saa7146_register_extension(&budget_extension);
}

-
static void __exit budget_ci_exit(void)
{
- DEB_EE((".\n"));
saa7146_unregister_extension(&budget_extension);
}

diff -uraNwB linux-2.6.10-rc1/drivers/media/dvb/ttpci/budget-core.c linux-2.6.10-rc1-patched/drivers/media/dvb/ttpci/budget-core.c
--- linux-2.6.10-rc1/drivers/media/dvb/ttpci/budget-core.c 2004-10-25 14:07:51.000000000 +0200
+++ linux-2.6.10-rc1-patched/drivers/media/dvb/ttpci/budget-core.c 2004-10-25 14:14:44.000000000 +0200
@@ -50,7 +49,7 @@

static int stop_ts_capture(struct budget *budget)
{
- DEB_EE(("budget: %p\n",budget));
+ dprintk(2, "budget: %p\n", budget);

if (--budget->feeding)
return budget->feeding;
@@ -65,7 +63,7 @@
{
struct saa7146_dev *dev=budget->dev;

- DEB_EE(("budget: %p\n",budget));
+ dprintk(2, "budget: %p\n", budget);

if (budget->feeding)
return ++budget->feeding;
@@ -171,7 +167,7 @@
struct budget *budget = (struct budget*) demux->priv;
int status;

- DEB_EE(("budget: %p\n",budget));
+ dprintk(2, "budget: %p\n", budget);

if (!demux->dmx.frontend)
return -EINVAL;
@@ -188,7 +184,7 @@
struct budget *budget = (struct budget *) demux->priv;
int status;

- DEB_EE(("budget: %p\n",budget));
+ dprintk(2, "budget: %p\n", budget);

spin_lock(&budget->feedlock);
status = stop_ts_capture (budget);
@@ -202,7 +197,7 @@
struct dvb_demux *dvbdemux=&budget->demux;
int ret;

- DEB_EE(("budget: %p\n",budget));
+ dprintk(2, "budget: %p\n", budget);

dvbdemux->priv = (void *) budget;

@@ -251,7 +245,7 @@
{
struct dvb_demux *dvbdemux=&budget->demux;

- DEB_EE(("budget: %p\n",budget));
+ dprintk(2, "budget: %p\n", budget);

dvb_net_release(&budget->dvb_net);

@@ -294,7 +288,7 @@

memset(budget, 0, sizeof(struct budget));

- DEB_EE(("dev: %p, budget: %p\n", dev, budget));
+ dprintk(2, "dev: %p, budget: %p\n", dev, budget);

budget->card = bi;
budget->dev = (struct saa7146_dev *) dev;
@@ -377,7 +370,7 @@
{
struct saa7146_dev *dev = budget->dev;

- DEB_EE(("budget: %p\n", budget));
+ dprintk(2, "budget: %p\n", budget);

budget_unregister (budget);

@@ -398,7 +391,7 @@
{
struct budget *budget = (struct budget*)dev->ext_priv;

- DEB_EE(("dev: %p, budget: %p\n",dev,budget));
+ dprintk(8, "dev: %p, budget: %p\n",dev,budget);

if (*isr & MASK_10)
tasklet_schedule (&budget->vpe_tasklet);
diff -uraNwB linux-2.6.10-rc1/drivers/media/dvb/ttpci/budget-patch.c linux-2.6.10-rc1-patched/drivers/media/dvb/ttpci/budget-patch.c
--- linux-2.6.10-rc1/drivers/media/dvb/ttpci/budget-patch.c 2004-10-25 14:07:52.000000000 +0200
+++ linux-2.6.10-rc1-patched/drivers/media/dvb/ttpci/budget-patch.c 2004-10-25 14:14:44.000000000 +0200
@@ -30,9 +30,9 @@
* the project's page is at http://www.linuxtv.org/dvb/
*/

-#include "budget.h"
#include "av7110.h"
#include "av7110_hw.h"
+#include "budget.h"

#define budget_patch budget

@@ -51,7 +51,7 @@
{
struct saa7146_dev *dev=budget->dev;

- DEB_EE(("budget: %p\n", budget));
+ dprintk(2, "budget: %p\n", budget);

if (count <= 0 || count > 4)
return -1;
@@ -71,7 +70,7 @@
{
int i;

- DEB_EE(("budget: %p\n", budget));
+ dprintk(2, "budget: %p\n", budget);

for (i = 2; i < length; i++)
budget_wdebi(budget, DEBINOSWAP, COMMAND + 2*i, (u32) buf[i], 2);
@@ -90,7 +88,7 @@
{
u16 buf[2] = {( COMTYPE_AUDIODAC << 8) | (state ? ON22K : OFF22K), 0};

- DEB_EE(("budget: %p\n", budget));
+ dprintk(2, "budget: %p\n", budget);
budget_av7110_send_fw_cmd(budget, buf, 2);
}

@@ -101,7 +98,7 @@
u16 buf[18] = { ((COMTYPE_AUDIODAC << 8) | SendDiSEqC),
16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };

- DEB_EE(("budget: %p\n", budget));
+ dprintk(2, "budget: %p\n", budget);

if (len>10)
len=10;
@@ -126,7 +122,7 @@
{
struct budget_patch *budget = fe->before_after_data;

- DEB_EE(("budget: %p\n", budget));
+ dprintk(2, "budget: %p\n", budget);

switch (cmd) {
case FE_SET_TONE:
@@ -171,7 +166,7 @@
if (!(budget = kmalloc (sizeof(struct budget_patch), GFP_KERNEL)))
return -ENOMEM;

- DEB_EE(("budget: %p\n",budget));
+ dprintk(2, "budget: %p\n", budget);

if ((err = ttpci_budget_init (budget, dev, info))) {
kfree (budget);
@@ -251,10 +244,8 @@
return saa7146_register_extension(&budget_extension);
}

-
static void __exit budget_patch_exit(void)
{
- DEB_EE((".\n"));
saa7146_unregister_extension(&budget_extension);
}

diff -uraNwB linux-2.6.10-rc1/drivers/media/dvb/ttpci/budget.c linux-2.6.10-rc1-patched/drivers/media/dvb/ttpci/budget.c
--- linux-2.6.10-rc1/drivers/media/dvb/ttpci/budget.c 2004-10-25 14:07:51.000000000 +0200
+++ linux-2.6.10-rc1-patched/drivers/media/dvb/ttpci/budget.c 2004-10-25 14:14:44.000000000 +0200
@@ -39,7 +39,7 @@
static void Set22K (struct budget *budget, int state)
{
struct saa7146_dev *dev=budget->dev;
- DEB_EE(("budget: %p\n",budget));
+ dprintk(2, "budget: %p\n", budget);
saa7146_setgpio(dev, 3, (state ? SAA7146_GPIO_OUTHI : SAA7146_GPIO_OUTLO));
}

@@ -51,7 +51,7 @@
static void DiseqcSendBit (struct budget *budget, int data)
{
struct saa7146_dev *dev=budget->dev;
- DEB_EE(("budget: %p\n",budget));
+ dprintk(2, "budget: %p\n", budget);

saa7146_setgpio(dev, 3, SAA7146_GPIO_OUTHI);
udelay(data ? 500 : 1000);
@@ -64,7 +64,7 @@
{
int i, par=1, d;

- DEB_EE(("budget: %p\n",budget));
+ dprintk(2, "budget: %p\n", budget);

for (i=7; i>=0; i--) {
d = (data>>i)&1;
@@ -81,7 +81,7 @@
struct saa7146_dev *dev=budget->dev;
int i;

- DEB_EE(("budget: %p\n",budget));
+ dprintk(2, "budget: %p\n", budget);

saa7146_setgpio(dev, 3, SAA7146_GPIO_OUTLO);
mdelay(16);
@@ -110,7 +110,7 @@
{
struct budget *budget = fe->before_after_data;

- DEB_EE(("budget: %p\n",budget));
+ dprintk(2, "budget: %p\n", budget);

switch (cmd) {
case FE_SET_TONE:
@@ -155,7 +155,7 @@
{
struct saa7146_dev *dev=budget->dev;

- DEB_EE(("budget: %p\n",budget));
+ dprintk(2, "budget: %p\n", budget);

switch (voltage) {
case SEC_VOLTAGE_13:
@@ -176,7 +176,7 @@
{
struct budget *budget = fe->before_after_data;

- DEB_EE(("budget: %p\n",budget));
+ dprintk(2, "budget: %p\n", budget);

switch (cmd) {
case FE_SET_VOLTAGE:
@@ -199,7 +199,7 @@
return -ENOMEM;
}

- DEB_EE(("dev:%p, info:%p, budget:%p\n",dev,info,budget));
+ dprintk(2, "dev:%p, info:%p, budget:%p\n", dev, info, budget);

dev->ext_priv = budget;

@@ -289,7 +289,6 @@

static void __exit budget_exit(void)
{
- DEB_EE((".\n"));
saa7146_unregister_extension(&budget_extension);
}

diff -uraNwB linux-2.6.10-rc1/drivers/media/dvb/ttpci/budget.h linux-2.6.10-rc1-patched/drivers/media/dvb/ttpci/budget.h
--- linux-2.6.10-rc1/drivers/media/dvb/ttpci/budget.h 2004-10-25 14:07:51.000000000 +0200
+++ linux-2.6.10-rc1-patched/drivers/media/dvb/ttpci/budget.h 2004-10-25 14:14:44.000000000 +0200
@@ -13,6 +13,13 @@

extern int budget_debug;

+#ifdef dprintk
+#undef dprintk
+#endif
+
+#define dprintk(level,args...) \
+ do { if ((budget_debug & level)) { printk("%s: %s(): ",__stringify(KBUILD_MODNAME), __FUNCTION__); printk(args); } } while (0)
+
struct budget_info {
char *name;
int type;


Attachments:
01-dvb-av7110-debug.diff (54.05 kB)

2004-10-27 09:59:51

by Michael Hunold

[permalink] [raw]
Subject: [PATCH][2/5] DVB: misc. updates to the dvb-core

- [DVB] ttusb_dec: add new 2000T type model number
- [DVB] dvb_ca_en50221: properly zero out private pointer
- [DVB] dvb-bt8xx: properly use a mutex when starting/stopping the dma engine, remove card list, it's not need anymore
- [DVB] bt878: fix hex <=> dec typo (missing 0x prefix), mark remove bt878_remove() function __devexit_p
- [DVB] dvb-core: add dvb_net_debug module parameter, remove some dead code

Signed-off-by: Michael Hunold <[email protected]>

diff -uraNwB linux-2.6.10-rc1/Documentation/dvb/readme.txt linux-2.6.10-rc1-patched/Documentation/dvb/readme.txt
--- linux-2.6.10-rc1/Documentation/dvb/readme.txt 2004-10-25 14:03:49.000000000 +0200
+++ linux-2.6.10-rc1-patched/Documentation/dvb/readme.txt 2004-10-25 14:14:41.000000000 +0200
@@ -41,9 +41,9 @@
various bt8xx based "budget" DVB cards
(Nebula, Pinnacle PCTV, Twinhan DST)

-"vp7041.txt"
-contains detailed informations about the
-Visionplus VisionDTV USB-Ter DVB-T adapter.
+"README.dibusb"
+contains detailed information about adapters
+based on DiBcom reference design.

"udev.txt"
how to get DVB and udev up and running.
diff -uraNwB linux-2.6.10-rc1/drivers/media/dvb/ttusb-dec/ttusb_dec.c linux-2.6.10-rc1-patched/drivers/media/dvb/ttusb-dec/ttusb_dec.c
--- linux-2.6.10-rc1/drivers/media/dvb/ttusb-dec/ttusb_dec.c 2004-10-25 14:07:50.000000000 +0200
+++ linux-2.6.10-rc1-patched/drivers/media/dvb/ttusb-dec/ttusb_dec.c 2004-10-25 14:14:44.000000000 +0200
@@ -1293,6 +1293,7 @@
ttusb_dec_set_model(dec, TTUSB_DEC3000S);
break;
case 0x00070009:
+ case 0x00070013:
ttusb_dec_set_model(dec, TTUSB_DEC2000T);
break;
case 0x00070011:
diff -uraNwB linux-2.6.10-rc1/drivers/media/dvb/frontends/grundig_29504-401.c linux-2.6.10-rc1-patched/drivers/media/dvb/frontends/grundig_29504-401.c
--- linux-2.6.10-rc1/drivers/media/dvb/frontends/grundig_29504-401.c 2004-10-25 14:07:57.000000000 +0200
+++ linux-2.6.10-rc1-patched/drivers/media/dvb/frontends/grundig_29504-401.c 2004-10-25 14:14:43.000000000 +0200
@@ -4,7 +4,7 @@

Copyright (C) 2001 Holger Waechtler <[email protected]>
for Convergence Integrated Media GmbH
- Marko Kohtala <[email protected]>
+ Marko Kohtala <[email protected]>

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
diff -uraNwB linux-2.6.10-rc1/drivers/media/dvb/dvb-core/dvb_ca_en50221.c linux-2.6.10-rc1-patched/drivers/media/dvb/dvb-core/dvb_ca_en50221.c
--- linux-2.6.10-rc1/drivers/media/dvb/dvb-core/dvb_ca_en50221.c 2004-10-25 14:07:54.000000000 +0200
+++ linux-2.6.10-rc1-patched/drivers/media/dvb/dvb-core/dvb_ca_en50221.c 2004-10-25 14:14:42.000000000 +0200
@@ -1500,6 +1499,7 @@
};

static struct dvb_device dvbdev_ca = {
+ .priv = NULL,
.users = 1,
.readers= 1,
.writers= 1,
diff -uraNwB linux-2.6.10-rc1/drivers/media/dvb/bt8xx/dvb-bt8xx.c linux-2.6.10-rc1-patched/drivers/media/dvb/bt8xx/dvb-bt8xx.c
--- linux-2.6.10-rc1/drivers/media/dvb/bt8xx/dvb-bt8xx.c 2004-10-25 14:07:49.000000000 +0200
+++ linux-2.6.10-rc1-patched/drivers/media/dvb/bt8xx/dvb-bt8xx.c 2004-10-25 14:14:41.000000000 +0200
@@ -68,20 +68,21 @@
{
struct dvb_demux *dvbdmx = dvbdmxfeed->demux;
struct dvb_bt8xx_card *card = dvbdmx->priv;
+ int rc;

dprintk("dvb_bt8xx: start_feed\n");

if (!dvbdmx->dmx.frontend)
return -EINVAL;

- if (card->active)
- return 0;
-
- card->active = 1;
-
-// bt878_start(card->bt, card->gpio_mode);
-
- return 0;
+ down(&card->lock);
+ card->nfeeds++;
+ rc = card->nfeeds;
+ if (card->nfeeds == 1)
+ bt878_start(card->bt, card->gpio_mode,
+ card->op_sync_orin, card->irq_err_ignore);
+ up(&card->lock);
+ return rc;
}

static int dvb_bt8xx_stop_feed(struct dvb_demux_feed *dvbdmxfeed)
@@ -94,12 +95,11 @@
if (!dvbdmx->dmx.frontend)
return -EINVAL;

- if (!card->active)
- return 0;
-
-// bt878_stop(card->bt);
-
- card->active = 0;
+ down(&card->lock);
+ card->nfeeds--;
+ if (card->nfeeds == 0)
+ bt878_stop(card->bt);
+ up(&card->lock);

return 0;
}
@@ -207,8 +207,6 @@

tasklet_init(&card->bt->tasklet, dvb_bt8xx_task, (unsigned long) card);

- bt878_start(card->bt, card->gpio_mode, card->op_sync_orin, card->irq_err_ignore);
-
return 0;
}

@@ -223,6 +221,7 @@
return -ENOMEM;

memset(card, 0, sizeof(*card));
+ init_MUTEX(&card->lock);
card->bttv_nr = sub->core->nr;
strncpy(card->card_name, sub->core->name, sizeof(sub->core->name));
card->i2c_adapter = &sub->core->i2c_adap;
@@ -230,6 +229,9 @@
switch(sub->core->type)
{
case BTTV_PINNACLESAT:
+#ifdef BTTV_DVICO_DVBT_LITE
+ case BTTV_DVICO_DVBT_LITE:
+#endif
card->gpio_mode = 0x0400C060;
card->op_sync_orin = 0;
card->irq_err_ignore = 0;
@@ -287,7 +289,10 @@
}

if (!(card->bt = dvb_bt8xx_878_match(card->bttv_nr, bttv_pci_dev))) {
- printk("dvb_bt8xx: unable to determine DMA core of card %d\n", card->bttv_nr);
+ printk("dvb_bt8xx: unable to determine DMA core of card %d,\n",
+ card->bttv_nr);
+ printk("dvb_bt8xx: if you have the ALSA bt87x audio driver "
+ "installed, try removing it.\n");

kfree(card);
return -EFAULT;
@@ -321,7 +326,6 @@
dvb_dmx_release(&card->demux);
dvb_unregister_adapter(card->dvb_adapter);

- list_del(&card->list);
kfree(card);

return 0;
diff -uraNwB linux-2.6.10-rc1/drivers/media/dvb/bt8xx/dvb-bt8xx.h linux-2.6.10-rc1-patched/drivers/media/dvb/bt8xx/dvb-bt8xx.h
--- linux-2.6.10-rc1/drivers/media/dvb/bt8xx/dvb-bt8xx.h 2004-10-25 14:07:49.000000000 +0200
+++ linux-2.6.10-rc1-patched/drivers/media/dvb/bt8xx/dvb-bt8xx.h 2004-10-25 14:14:41.000000000 +0200
@@ -28,8 +28,8 @@
#include "bttv.h"

struct dvb_bt8xx_card {
- struct list_head list;
- u8 active;
+ struct semaphore lock;
+ int nfeeds;
char card_name[32];
struct dvb_adapter *dvb_adapter;
struct bt878 *bt;

diff -uraNwB linux-2.6.10-rc1/drivers/media/dvb/bt8xx/bt878.c linux-2.6.10-rc1-patched/drivers/media/dvb/bt8xx/bt878.c
--- linux-2.6.10-rc1/drivers/media/dvb/bt8xx/bt878.c 2004-10-25 14:07:49.000000000 +0200
+++ linux-2.6.10-rc1-patched/drivers/media/dvb/bt8xx/bt878.c 2004-10-25 14:14:41.000000000 +0200
@@ -511,7 +511,7 @@
printk("bt878(%d): unloading\n", bt->nr);

/* turn off all capturing, DMA and IRQs */
- btand(~13, BT878_AGPIO_DMA_CTL);
+ btand(~0x13, BT878_AGPIO_DMA_CTL);

/* first disable interrupts before unmapping the memory! */
btwrite(0, BT878_AINT_MASK);
@@ -554,7 +554,7 @@
.name = "bt878",
.id_table = bt878_pci_tbl,
.probe = bt878_probe,
- .remove = __devexit_p(bt878_remove),
+ .remove = bt878_remove,
};

static int bt878_pci_driver_registered = 0;
diff -uraNwB linux-2.6.10-rc1/drivers/media/dvb/dvb-core/dvb_net.c linux-2.6.10-rc1-patched/drivers/media/dvb/dvb-core/dvb_net.c
--- linux-2.6.10-rc1/drivers/media/dvb/dvb-core/dvb_net.c 2004-10-25 14:07:55.000000000 +0200
+++ linux-2.6.10-rc1-patched/drivers/media/dvb/dvb-core/dvb_net.c 2004-10-25 14:14:43.000000000 +0200
@@ -37,10 +37,18 @@
#include <linux/uio.h>
#include <asm/uaccess.h>
#include <linux/crc32.h>
+#include <linux/version.h>

#include "dvb_demux.h"
#include "dvb_net.h"

+static int dvb_net_debug;
+module_param(dvb_net_debug, int, 0444);
+MODULE_PARM_DESC(dvb_net_debug, "enable debug messages");
+
+#define dprintk(x...) do { if (dvb_net_debug) printk(x); } while (0)
+
+
static inline __u32 iov_crc32( __u32 c, struct kvec *iov, unsigned int cnt )
{
unsigned int j;
@@ -50,13 +58,6 @@
}


-#if 1
-#define dprintk(x...) printk(x)
-#else
-#define dprintk(x...)
-#endif
-
-
#define DVB_NET_MULTICAST_MAX 10

#define isprint(c) ((c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z') || (c >= '0' && c <= '9'))
@@ -917,14 +922,6 @@
}


-static int dvb_net_set_config(struct net_device *dev, struct ifmap *map)
-{
- if (netif_running(dev))
- return -EBUSY;
- return 0;
-}
-
-
static void wq_restart_net_feed (void *data)
{
struct net_device *dev = data;
@@ -983,7 +979,6 @@
dev->hard_start_xmit = dvb_net_tx;
dev->get_stats = dvb_net_get_stats;
dev->set_multicast_list = dvb_net_set_multicast_list;
- dev->set_config = dvb_net_set_config;
dev->set_mac_address = dvb_net_set_mac;
dev->mtu = 4096;
dev->mc_count = 0;


Attachments:
02-dvb-misc.diff (8.16 kB)

2004-10-27 10:04:25

by Michael Hunold

[permalink] [raw]
Subject: [PATCH][3/5] DVB: add new driver

- [DVB] add new driver for the Terratec CinergyT2/qanu USB2 DVB-T receiver, thanks to Daniel Mack and Holger Waechtler

Signed-off-by: Michael Hunold <[email protected]>

diff -uraNwB linux-2.6.10-rc1/drivers/media/dvb/Kconfig linux-2.6.10-rc1-patched/drivers/media/dvb/Kconfig
--- linux-2.6.10-rc1/drivers/media/dvb/Kconfig 2004-10-25 14:07:50.000000000 +0200
+++ linux-2.6.10-rc1-patched/drivers/media/dvb/Kconfig 2004-10-25 14:14:41.000000000 +0200
@@ -32,6 +32,7 @@
source "drivers/media/dvb/ttusb-budget/Kconfig"
source "drivers/media/dvb/ttusb-dec/Kconfig"
source "drivers/media/dvb/dibusb/Kconfig"
+source "drivers/media/dvb/cinergyT2/Kconfig"

comment "Supported FlexCopII (B2C2) Adapters"
depends on DVB_CORE && PCI
diff -uraNwB linux-2.6.10-rc1/drivers/media/dvb/Makefile linux-2.6.10-rc1-patched/drivers/media/dvb/Makefile
--- linux-2.6.10-rc1/drivers/media/dvb/Makefile 2004-10-25 14:07:53.000000000 +0200
+++ linux-2.6.10-rc1-patched/drivers/media/dvb/Makefile 2004-10-25 14:14:41.000000000 +0200
@@ -2,4 +2,4 @@
# Makefile for the kernel multimedia device drivers.
#

-obj-y := dvb-core/ frontends/ ttpci/ ttusb-dec/ ttusb-budget/ b2c2/ bt8xx/ dibusb/
+obj-y := dvb-core/ frontends/ ttpci/ ttusb-dec/ ttusb-budget/ b2c2/ bt8xx/ dibusb/ cinergyT2/
diff -uraNwB linux-2.6.10-rc1/drivers/media/dvb/cinergyT2/Kconfig linux-2.6.10-rc1-patched/drivers/media/dvb/cinergyT2/Kconfig
--- linux-2.6.10-rc1/drivers/media/dvb/cinergyT2/Kconfig 1970-01-01 01:00:00.000000000 +0100
+++ linux-2.6.10-rc1-patched/drivers/media/dvb/cinergyT2/Kconfig 2004-10-15 17:22:20.000000000 +0200
@@ -0,0 +1,59 @@
+config DVB_CINERGYT2
+ tristate "Terratec CinergyT2/qanu USB2 DVB-T receiver"
+ depends on DVB_CORE && USB
+ help
+ Support for "TerraTec CinergyT2" USB2.0 Highspeed DVB Receivers
+
+ Say Y if you own such a device and want to use it.
+
+
+config DVB_CINERGYT2_TUNING
+ bool "sophisticated fine-tuning for CinergyT2 cards"
+ depends on DVB_CINERGYT2
+ help
+ Here you can fine-tune some parameters of the CinergyT2 driver.
+
+ Normally you don't need to touch this, but in exotic setups you
+ may fine-tune your setup and adjust e.g. DMA buffer sizes for
+ a particular application.
+
+
+config DVB_CINERGYT2_STREAM_URB_COUNT
+ int "Number of queued USB Request Blocks for Highspeed Stream Transfers"
+ depends on DVB_CINERGYT2_TUNING
+ default "32"
+ help
+ USB Request Blocks for Highspeed Stream transfers are queued in a
+ for the Host Controller. Usually the default value is a safe choice.
+
+ You may increase this number if you are using this device in a
+ Server Environment with many high-traffic USB Highspeed devices
+ sharing the same USB bus.
+
+
+config DVB_CINERGYT2_STREAM_BUF_SIZE
+ int "Size of URB Stream Buffers for Highspeed Transfers"
+ depends on DVB_CINERGYT2_TUNING
+ default "512"
+ help
+ Should be a multiple of native buffer size of 512 bytes.
+ Default value is a safe choice.
+
+ You may increase this number if you are using this device in a
+ Server Environment with many high-traffic USB Highspeed devices
+ sharing the same USB bus.
+
+
+config DVB_CINERGYT2_ENABLE_RC_INPUT_DEVICE
+ bool "Register the onboard IR Remote Control Receiver as Input Device"
+ depends on DVB_CINERGYT2_TUNING
+ default "yes"
+ help
+ Enable this option if you want to use the onboard Infrared Remote
+ Control Receiver as Linux-Input device.
+
+ Right now only the keycode table for the default Remote Control
+ delivered with the device is supported, please see the driver
+ source code to find out how to add support for other controls.
+
+
diff -uraNwB linux-2.6.10-rc1/drivers/media/dvb/cinergyT2/Makefile linux-2.6.10-rc1-patched/drivers/media/dvb/cinergyT2/Makefile
--- linux-2.6.10-rc1/drivers/media/dvb/cinergyT2/Makefile 1970-01-01 01:00:00.000000000 +0100
+++ linux-2.6.10-rc1-patched/drivers/media/dvb/cinergyT2/Makefile 2004-10-15 17:15:48.000000000 +0200
@@ -0,0 +1,3 @@
+obj-$(CONFIG_DVB_CINERGYT2) += cinergyT2.o
+
+EXTRA_CFLAGS = -Idrivers/media/dvb/dvb-core/
diff -uraN a/linux-2.6.10-rc1-patched/drivers/media/dvb/cinergyT2/cinergyT2.c b/linux-2.6.10-rc1-patched/drivers/media/dvb/cinergyT2/cinergyT2.c
--- a/drivers/media/dvb/cinergyT2/cinergyT2.c 1970-01-01 01:00:00.000000000 +0100
+++ b/drivers/media/dvb/cinergyT2/cinergyT2.c 2004-10-26 15:17:54.000000000 +0200
@@ -0,0 +1,811 @@
+/*
+ * TerraTec Cinergy T?/qanu USB2 DVB-T adapter.
+ *
+ * Copyright (C) 2004 Daniel Mack <[email protected]> and
+ * Holger Waechtler <[email protected]>
+ *
+ * Protocol Spec published on http://qanu.de/specs/terratec_cinergyT2.pdf
+ *
+ * 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; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ */
+
+#include <linux/config.h>
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/slab.h>
+#include <linux/usb.h>
+#include <linux/pci.h>
+#include <linux/input.h>
+#include <linux/dvb/frontend.h>
+
+#include "dmxdev.h"
+#include "dvb_demux.h"
+#include "dvb_net.h"
+
+#ifdef CONFIG_DVB_CINERGYT2_TUNING
+ #define STREAM_URB_COUNT (CONFIG_DVB_CINERGYT2_STREAM_URB_COUNT)
+ #define STREAM_BUF_SIZE (CONFIG_DVB_CINERGYT2_STREAM_BUF_SIZE)
+ #ifdef CONFIG_DVB_CINERGYT2_ENABLE_RC_INPUT_DEVICE
+ #define ENABLE_RC (1)
+ #endif
+#else
+ #define STREAM_URB_COUNT (32)
+ #define STREAM_BUF_SIZE (512)
+ #define ENABLE_RC (1)
+#endif
+
+#define DRIVER_NAME "TerraTec/qanu USB2.0 Highspeed DVB-T Receiver"
+
+static int debug;
+module_param_named(debug, debug, int, 0644);
+MODULE_PARM_DESC(debug, "Turn on/off debugging (default:off).");
+
+#define dprintk(level, args...) \
+ do { if ((debug & level)) { printk("%s: %s(): ",__stringify(KBUILD_MODNAME), __FUNCTION__); printk(args); } } while (0)
+
+enum cinergyt2_ep1_cmd {
+ CINERGYT2_EP1_PID_TABLE_RESET = 0x01,
+ CINERGYT2_EP1_PID_SETUP = 0x02,
+ CINERGYT2_EP1_CONTROL_STREAM_TRANSFER = 0x03,
+ CINERGYT2_EP1_SET_TUNER_PARAMETERS = 0x04,
+ CINERGYT2_EP1_GET_TUNER_STATUS = 0x05,
+ CINERGYT2_EP1_START_SCAN = 0x06,
+ CINERGYT2_EP1_CONTINUE_SCAN = 0x07,
+ CINERGYT2_EP1_GET_RC_EVENTS = 0x08,
+ CINERGYT2_EP1_SLEEP_MODE = 0x09
+};
+
+static struct dvb_frontend_info cinergyt2_fe_info = {
+ .name = DRIVER_NAME,
+ .type = FE_OFDM,
+ .frequency_min = 174000000,
+ .frequency_max = 862000000,
+ .frequency_stepsize = 166667,
+ .notifier_delay = 0,
+ .caps = FE_CAN_INVERSION_AUTO | 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_QPSK | 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 | FE_CAN_RECOVER | FE_CAN_MUTE_TS
+};
+
+struct cinergyt2 {
+ struct dvb_demux demux;
+ struct usb_device *udev;
+ struct semaphore sem;
+ struct dvb_adapter *adapter;
+ struct dvb_device *fedev;
+ struct dmxdev dmxdev;
+ struct dvb_net dvbnet;
+
+ int streaming;
+
+ void *streambuf;
+ dma_addr_t streambuf_dmahandle;
+ struct urb *stream_urb[STREAM_URB_COUNT];
+
+#ifdef ENABLE_RC
+ struct input_dev rc_input_dev;
+ struct work_struct rc_query_work;
+ int rc_input_event;
+#endif
+};
+
+enum {
+ CINERGYT2_RC_EVENT_TYPE_NONE = 0x00,
+ CINERGYT2_RC_EVENT_TYPE_NEC = 0x01,
+ CINERGYT2_RC_EVENT_TYPE_RC5 = 0x02
+};
+
+struct cinergyt2_rc_event {
+ char type;
+ uint32_t value;
+} __attribute__((packed));
+
+static const uint32_t rc_keys [] = {
+ CINERGYT2_RC_EVENT_TYPE_NEC, 0xfe01eb04, KEY_POWER,
+ CINERGYT2_RC_EVENT_TYPE_NEC, 0xfd02eb04, KEY_1,
+ CINERGYT2_RC_EVENT_TYPE_NEC, 0xfc03eb04, KEY_2,
+ CINERGYT2_RC_EVENT_TYPE_NEC, 0xfb04eb04, KEY_3,
+ CINERGYT2_RC_EVENT_TYPE_NEC, 0xfa05eb04, KEY_4,
+ CINERGYT2_RC_EVENT_TYPE_NEC, 0xf906eb04, KEY_5,
+ CINERGYT2_RC_EVENT_TYPE_NEC, 0xf807eb04, KEY_6,
+ CINERGYT2_RC_EVENT_TYPE_NEC, 0xf708eb04, KEY_7,
+ CINERGYT2_RC_EVENT_TYPE_NEC, 0xf609eb04, KEY_8,
+ CINERGYT2_RC_EVENT_TYPE_NEC, 0xf50aeb04, KEY_9,
+ CINERGYT2_RC_EVENT_TYPE_NEC, 0xf30ceb04, KEY_0,
+ CINERGYT2_RC_EVENT_TYPE_NEC, 0xf40beb04, KEY_VIDEO,
+ CINERGYT2_RC_EVENT_TYPE_NEC, 0xf20deb04, KEY_REFRESH,
+ CINERGYT2_RC_EVENT_TYPE_NEC, 0xf10eeb04, KEY_SELECT,
+ CINERGYT2_RC_EVENT_TYPE_NEC, 0xf00feb04, KEY_EPG,
+ CINERGYT2_RC_EVENT_TYPE_NEC, 0xef10eb04, KEY_UP,
+ CINERGYT2_RC_EVENT_TYPE_NEC, 0xeb14eb04, KEY_DOWN,
+ CINERGYT2_RC_EVENT_TYPE_NEC, 0xee11eb04, KEY_LEFT,
+ CINERGYT2_RC_EVENT_TYPE_NEC, 0xec13eb04, KEY_RIGHT,
+ CINERGYT2_RC_EVENT_TYPE_NEC, 0xed12eb04, KEY_OK,
+ CINERGYT2_RC_EVENT_TYPE_NEC, 0xea15eb04, KEY_TEXT,
+ CINERGYT2_RC_EVENT_TYPE_NEC, 0xe916eb04, KEY_INFO,
+ CINERGYT2_RC_EVENT_TYPE_NEC, 0xe817eb04, KEY_RED,
+ CINERGYT2_RC_EVENT_TYPE_NEC, 0xe718eb04, KEY_GREEN,
+ CINERGYT2_RC_EVENT_TYPE_NEC, 0xe619eb04, KEY_YELLOW,
+ CINERGYT2_RC_EVENT_TYPE_NEC, 0xe51aeb04, KEY_BLUE,
+ CINERGYT2_RC_EVENT_TYPE_NEC, 0xe31ceb04, KEY_VOLUMEUP,
+ CINERGYT2_RC_EVENT_TYPE_NEC, 0xe11eeb04, KEY_VOLUMEDOWN,
+ CINERGYT2_RC_EVENT_TYPE_NEC, 0xe21deb04, KEY_MUTE,
+ CINERGYT2_RC_EVENT_TYPE_NEC, 0xe41beb04, KEY_CHANNELUP,
+ CINERGYT2_RC_EVENT_TYPE_NEC, 0xe01feb04, KEY_CHANNELDOWN,
+ CINERGYT2_RC_EVENT_TYPE_NEC, 0xbf40eb04, KEY_PAUSE,
+ CINERGYT2_RC_EVENT_TYPE_NEC, 0xb34ceb04, KEY_PLAY,
+ CINERGYT2_RC_EVENT_TYPE_NEC, 0xa758eb04, KEY_RECORD,
+ CINERGYT2_RC_EVENT_TYPE_NEC, 0xab54eb04, KEY_PREVIOUS,
+ CINERGYT2_RC_EVENT_TYPE_NEC, 0xb748eb04, KEY_STOP,
+ CINERGYT2_RC_EVENT_TYPE_NEC, 0xa35ceb04, KEY_NEXT
+};
+
+static void cinergyt2_stream_irq (struct urb *urb, struct pt_regs *regs);
+
+static int cinergyt2_submit_stream_urb (struct cinergyt2 *cinergyt2, struct urb *urb)
+{
+ int err;
+
+ usb_fill_bulk_urb(urb,
+ cinergyt2->udev,
+ usb_rcvbulkpipe(cinergyt2->udev, 0x2),
+ urb->transfer_buffer,
+ STREAM_BUF_SIZE,
+ cinergyt2_stream_irq,
+ cinergyt2);
+
+ if ((err = usb_submit_urb(urb, GFP_ATOMIC)))
+ dprintk(1, "urb submission failed (err = %i)!\n", err);
+
+ return err;
+}
+
+static void cinergyt2_stream_irq (struct urb *urb, struct pt_regs *regs)
+{
+ struct cinergyt2 *cinergyt2 = urb->context;
+
+ if (urb->actual_length > 0)
+ dvb_dmx_swfilter(&cinergyt2->demux,
+ urb->transfer_buffer, urb->actual_length);
+
+ if (cinergyt2->streaming)
+ cinergyt2_submit_stream_urb(cinergyt2, urb);
+}
+
+static void cinergyt2_free_stream_urbs (struct cinergyt2 *cinergyt2)
+{
+ int i;
+
+ for (i=0; i<STREAM_URB_COUNT; i++)
+ if (cinergyt2->stream_urb[i])
+ usb_free_urb(cinergyt2->stream_urb[i]);
+
+ pci_free_consistent(NULL, STREAM_URB_COUNT*STREAM_BUF_SIZE,
+ cinergyt2->streambuf, cinergyt2->streambuf_dmahandle);
+}
+
+static int cinergyt2_alloc_stream_urbs (struct cinergyt2 *cinergyt2)
+{
+ int i;
+
+ cinergyt2->streambuf = pci_alloc_consistent(NULL,
+ STREAM_URB_COUNT*STREAM_BUF_SIZE,
+ &cinergyt2->streambuf_dmahandle);
+ if (!cinergyt2->streambuf) {
+ dprintk(1, "failed to alloc consistent stream memory area, bailing out!\n");
+ return -ENOMEM;
+ }
+
+ memset(cinergyt2->streambuf, 0, STREAM_URB_COUNT*STREAM_BUF_SIZE);
+
+ for (i=0; i<STREAM_URB_COUNT; i++) {
+ struct urb *urb;
+
+ if (!(urb = usb_alloc_urb(0, GFP_ATOMIC))) {
+ dprintk(1, "failed to alloc consistent stream urbs, bailing out!\n");
+ cinergyt2_free_stream_urbs(cinergyt2);
+ return -ENOMEM;
+ }
+
+ urb->transfer_buffer = cinergyt2->streambuf + i * STREAM_BUF_SIZE;
+ urb->transfer_buffer_length = STREAM_BUF_SIZE;
+
+ cinergyt2->stream_urb[i] = urb;
+ }
+
+ return 0;
+}
+
+static void cinergyt2_stop_stream_xfer (struct cinergyt2 *cinergyt2)
+{
+ int i;
+
+ for (i=0; i<STREAM_URB_COUNT; i++)
+ if (cinergyt2->stream_urb[i])
+ usb_unlink_urb(cinergyt2->stream_urb[i]);
+}
+
+static int cinergyt2_start_stream_xfer (struct cinergyt2 *cinergyt2)
+{
+ int i, err;
+
+ for (i=0; i<STREAM_URB_COUNT; i++) {
+ if ((err = cinergyt2_submit_stream_urb(cinergyt2, cinergyt2->stream_urb[i]))) {
+ cinergyt2_stop_stream_xfer(cinergyt2);
+ dprintk(1, "failed urb submission (%i: err = %i)!\n", i, err);
+ return err;
+ }
+ }
+
+ return 0;
+}
+
+static int cinergyt2_command (struct cinergyt2 *cinergyt2,
+ char *send_buf, int send_buf_len,
+ char *rec_buf, int rec_buf_len)
+{
+ int ret;
+ int actual_len;
+ char dummy;
+
+ if (down_interruptible(&cinergyt2->sem))
+ return -EBUSY;
+
+ ret = usb_bulk_msg(cinergyt2->udev, usb_sndbulkpipe(cinergyt2->udev, 1),
+ send_buf, send_buf_len, &actual_len, HZ);
+
+ if (ret)
+ dprintk(1, "usb_bulk_msg() (send) failed, err %i\n", ret);
+
+ if (!rec_buf)
+ rec_buf = &dummy;
+
+ ret = usb_bulk_msg(cinergyt2->udev, usb_rcvbulkpipe(cinergyt2->udev, 1),
+ rec_buf, rec_buf_len, &actual_len, HZ);
+
+ if (ret)
+ dprintk(1, "usb_bulk_msg() (read) failed, err %i\n", ret);
+
+ up(&cinergyt2->sem);
+
+ return ret ? ret : actual_len;
+}
+
+static void cinergyt2_control_stream_transfer (struct cinergyt2 *cinergyt2, int enable)
+{
+ char buf [] = { CINERGYT2_EP1_CONTROL_STREAM_TRANSFER, enable ? 1 : 0 };
+ cinergyt2_command(cinergyt2, buf, sizeof(buf), NULL, 0);
+}
+
+static void cinergyt2_control_sleep_mode (struct cinergyt2 *cinergyt2, int sleep)
+{
+ char buf [] = { CINERGYT2_EP1_SLEEP_MODE, sleep ? 1 : 0 };
+ cinergyt2_command(cinergyt2, buf, sizeof(buf), NULL, 0);
+}
+
+static int cinergyt2_start_feed(struct dvb_demux_feed *dvbdmxfeed)
+{
+ struct dvb_demux *demux = dvbdmxfeed->demux;
+ struct cinergyt2 *cinergyt2 = demux->priv;
+
+
+ if (cinergyt2->streaming == 0) {
+ if (cinergyt2_start_stream_xfer (cinergyt2) == 0)
+ cinergyt2_control_stream_transfer (cinergyt2, 1);
+ }
+
+ cinergyt2->streaming++;
+
+ return 0;
+}
+
+static int cinergyt2_stop_feed(struct dvb_demux_feed *dvbdmxfeed)
+{
+ struct dvb_demux *demux = dvbdmxfeed->demux;
+ struct cinergyt2 *cinergyt2 = demux->priv;
+
+ if (--cinergyt2->streaming == 0) {
+ cinergyt2_control_stream_transfer(cinergyt2, 0);
+ cinergyt2_stop_stream_xfer(cinergyt2);
+ }
+
+ return 0;
+}
+
+/**
+ * convert linux-dvb frontend parameter set into TPS.
+ * See ETSI ETS-300744, section 4.6.2, table 9 for details.
+ *
+ * This function is probably reusable and may better get placed in a support
+ * library.
+ *
+ * We replace errornous fields by default TPS fields (the ones with value 0).
+ */
+
+static uint16_t compute_tps (struct dvb_frontend_parameters *param)
+{
+ uint16_t tps = 0;
+ struct dvb_ofdm_parameters *op = &param->u.ofdm;
+
+ switch (op->code_rate_HP) {
+ case FEC_2_3:
+ tps |= (1 << 7);
+ break;
+ case FEC_3_4:
+ tps |= (2 << 7);
+ break;
+ case FEC_5_6:
+ tps |= (3 << 7);
+ break;
+ case FEC_7_8:
+ tps |= (4 << 7);
+ break;
+ case FEC_1_2:
+ case FEC_AUTO:
+ default:
+ /* tps |= (0 << 7) */;
+ }
+
+ switch (op->code_rate_LP) {
+ case FEC_2_3:
+ tps |= (1 << 4);
+ break;
+ case FEC_3_4:
+ tps |= (2 << 4);
+ break;
+ case FEC_5_6:
+ tps |= (3 << 4);
+ break;
+ case FEC_7_8:
+ tps |= (4 << 4);
+ break;
+ case FEC_1_2:
+ case FEC_AUTO:
+ default:
+ /* tps |= (0 << 4) */;
+ }
+
+ switch (op->constellation) {
+ case QAM_16:
+ tps |= (1 << 13);
+ break;
+ case QAM_64:
+ tps |= (2 << 13);
+ break;
+ case QPSK:
+ default:
+ /* tps |= (0 << 13) */;
+ }
+
+ switch (op->transmission_mode) {
+ case TRANSMISSION_MODE_8K:
+ tps |= (1 << 0);
+ break;
+ case TRANSMISSION_MODE_2K:
+ default:
+ /* tps |= (0 << 0) */;
+ }
+
+ switch (op->guard_interval) {
+ case GUARD_INTERVAL_1_16:
+ tps |= (1 << 2);
+ break;
+ case GUARD_INTERVAL_1_8:
+ tps |= (2 << 2);
+ break;
+ case GUARD_INTERVAL_1_4:
+ tps |= (3 << 2);
+ break;
+ case GUARD_INTERVAL_1_32:
+ default:
+ /* tps |= (0 << 2) */;
+ }
+
+ switch (op->hierarchy_information) {
+ case HIERARCHY_1:
+ tps |= (1 << 10);
+ break;
+ case HIERARCHY_2:
+ tps |= (2 << 10);
+ break;
+ case HIERARCHY_4:
+ tps |= (3 << 10);
+ break;
+ case HIERARCHY_NONE:
+ default:
+ /* tps |= (0 << 10) */;
+ }
+
+ return tps;
+}
+
+struct dvbt_set_parameters_msg {
+ uint8_t cmd;
+ uint32_t freq;
+ uint8_t bandwidth;
+ uint16_t tps;
+ uint8_t flags;
+} __attribute__((packed));
+
+struct dvbt_get_parameters_msg {
+ uint32_t freq;
+ uint8_t bandwidth;
+ uint16_t tps;
+ uint8_t flags;
+ uint16_t gain;
+ uint8_t snr;
+ uint32_t viterbi_error_rate;
+ uint32_t rs_error_rate;
+ uint32_t uncorrected_block_count;
+ uint8_t lock_bits;
+ uint8_t prev_lock_bits;
+} __attribute__((packed));
+
+static int cinergyt2_fe_open (struct inode *inode, struct file *file)
+{
+ struct dvb_device *dvbdev = file->private_data;
+ cinergyt2_control_sleep_mode((struct cinergyt2 *) dvbdev->priv, 0);
+ return dvb_generic_open(inode, file);
+}
+
+static int cinergyt2_fe_release (struct inode *inode, struct file *file)
+{
+ struct dvb_device *dvbdev = file->private_data;
+ cinergyt2_control_sleep_mode((struct cinergyt2 *) dvbdev->priv, 1);
+ return dvb_generic_release (inode, file);
+}
+
+static int cinergyt2_fe_ioctl (struct inode *inode, struct file *file,
+ unsigned int cmd, void *arg)
+{
+ struct dvb_device *dvbdev = file->private_data;
+ struct cinergyt2 *cinergyt2 = dvbdev->priv;
+ int ret = 0;
+
+ switch (cmd) {
+ case FE_GET_INFO:
+ memcpy (arg, &cinergyt2_fe_info, sizeof(struct dvb_frontend_info));
+ break;
+
+ case FE_READ_STATUS:
+ {
+ struct dvbt_get_parameters_msg msg;
+ char cmd = CINERGYT2_EP1_GET_TUNER_STATUS;
+ fe_status_t *status = arg;
+
+ *status = 0;
+
+ cinergyt2_command(cinergyt2, &cmd, 1, (char *) &msg, sizeof(msg));
+
+ if (msg.lock_bits & (1 << 6))
+ *status |= FE_HAS_LOCK;
+ if (msg.lock_bits & (1 << 5))
+ *status |= FE_HAS_SYNC;
+ if (msg.lock_bits & (1 << 4))
+ *status |= FE_HAS_CARRIER;
+ if (msg.lock_bits & (1 << 1))
+ *status |= FE_HAS_VITERBI;
+
+ break;
+ }
+
+ case FE_READ_BER:
+ {
+ struct dvbt_get_parameters_msg msg;
+ char cmd = CINERGYT2_EP1_GET_TUNER_STATUS;
+ u32 *ber = (u32 *) arg;
+
+ cinergyt2_command(cinergyt2, &cmd, 1, (char *) &msg, sizeof(msg));
+
+ *ber = le32_to_cpu(msg.viterbi_error_rate);
+
+ break;
+ }
+
+ case FE_READ_SIGNAL_STRENGTH:
+ {
+ struct dvbt_get_parameters_msg msg;
+ char cmd = CINERGYT2_EP1_GET_TUNER_STATUS;
+ u16 *signal = (u16 *) arg;
+
+ cinergyt2_command(cinergyt2, &cmd, 1, (char *) &msg, sizeof(msg));
+
+ *signal = ~(le16_to_cpu(msg.gain));
+
+ break;
+ }
+
+ case FE_READ_SNR:
+ {
+ struct dvbt_get_parameters_msg msg;
+ char cmd = CINERGYT2_EP1_GET_TUNER_STATUS;
+ u16 *snr = (u16 *) arg;
+
+ cinergyt2_command(cinergyt2, &cmd, 1, (char *) &msg, sizeof(msg));
+
+ *snr = (msg.snr << 8) | msg.snr;
+
+ break;
+ }
+
+ case FE_READ_UNCORRECTED_BLOCKS:
+ {
+ struct dvbt_get_parameters_msg msg;
+ char cmd = CINERGYT2_EP1_GET_TUNER_STATUS;
+ u32 *ubc = (u32 *) arg;
+
+ cinergyt2_command(cinergyt2, &cmd, 1, (char *) &msg, sizeof(msg));
+
+ *ubc = le32_to_cpu(msg.uncorrected_block_count);
+
+ break;
+ }
+
+ case FE_SET_FRONTEND:
+ {
+ struct dvb_frontend_parameters *p = (void*) arg;
+ struct dvb_ofdm_parameters *op = &p->u.ofdm;
+ struct dvbt_set_parameters_msg msg;
+
+ msg.cmd = CINERGYT2_EP1_SET_TUNER_PARAMETERS;
+ msg.tps = cpu_to_le16(compute_tps(p));
+ msg.freq = cpu_to_le32(p->frequency / 1000);
+ msg.bandwidth = 8 - op->bandwidth - BANDWIDTH_8_MHZ;
+
+ cinergyt2_command(cinergyt2, (char *) &msg, sizeof(msg), NULL, 0);
+
+ break;
+ }
+
+ case FE_GET_FRONTEND:
+ /**
+ * trivial to implement (see struct dvbt_get_parameters_msg).
+ * equivalent to FE_READ ioctls, but needs
+ * TPS -> linux-dvb parameter set conversion. Feel free
+ * to implement this and send us a patch if you need this
+ * functionality.
+ */
+ break;
+
+ default:
+ ret = -EINVAL;
+ break;
+ }
+
+ return ret;
+}
+
+static
+struct file_operations cinergyt2_fe_fops = {
+ .owner = THIS_MODULE,
+ .ioctl = dvb_generic_ioctl,
+ /**
+ * do we really need this? If so, let's implement it via
+ * schedule_delayed_work() similiar to the IR code.
+ */
+ /*.poll = cinergyt2_fe_poll, */
+ .open = cinergyt2_fe_open,
+ .release = cinergyt2_fe_release
+};
+
+static struct dvb_device cinergyt2_fe_template = {
+ .users = ~0,
+ .writers = 1,
+ .readers = (~0)-1,
+ .fops = &cinergyt2_fe_fops,
+ .kernel_ioctl = cinergyt2_fe_ioctl
+};
+
+#ifdef ENABLE_RC
+static void cinergyt2_query_rc (void *data)
+{
+ struct cinergyt2 *cinergyt2 = (struct cinergyt2 *) data;
+ char buf [1] = { CINERGYT2_EP1_GET_RC_EVENTS };
+ struct cinergyt2_rc_event rc_events[12];
+ int n, len;
+
+ len = cinergyt2_command(cinergyt2, buf, sizeof(buf),
+ (char *) rc_events, sizeof(rc_events));
+
+ for (n=0; len>0 && n<(len/sizeof(rc_events[0])); n++) {
+ int i;
+
+ if (rc_events[n].type == CINERGYT2_RC_EVENT_TYPE_NEC &&
+ rc_events[n].value == ~0)
+ {
+ /**
+ * keyrepeat bit. If we would handle this properly
+ * we would need to emit down events as long the
+ * keyrepeat goes, a up event if no further
+ * repeat bits occur. Would need a timer to implement
+ * and no other driver does this, so we simply
+ * emit the last key up/down sequence again.
+ */
+ } else {
+ cinergyt2->rc_input_event = KEY_MAX;
+ for (i=0; i<sizeof(rc_keys)/sizeof(rc_keys[0]); i+=3) {
+ if (rc_keys[i+0] == rc_events[n].type &&
+ rc_keys[i+1] == rc_events[n].value)
+ {
+ cinergyt2->rc_input_event = rc_keys[i+2];
+ break;
+ }
+ }
+ }
+
+ if (cinergyt2->rc_input_event != KEY_MAX) {
+ input_report_key(&cinergyt2->rc_input_dev, cinergyt2->rc_input_event, 1);
+ input_report_key(&cinergyt2->rc_input_dev, cinergyt2->rc_input_event, 0);
+ input_sync(&cinergyt2->rc_input_dev);
+ }
+ }
+
+ schedule_delayed_work(&cinergyt2->rc_query_work, (HZ/5));
+}
+#endif
+
+static int cinergyt2_probe (struct usb_interface *intf, const struct usb_device_id *id)
+{
+ struct cinergyt2 *cinergyt2;
+ int i, err;
+
+ if (!(cinergyt2 = kmalloc (sizeof(struct cinergyt2), GFP_KERNEL))) {
+ dprintk(1, "out of memory?!?\n");
+ return -ENOMEM;
+ }
+
+ memset (cinergyt2, 0, sizeof (struct cinergyt2));
+ usb_set_intfdata (intf, (void *) cinergyt2);
+
+ init_MUTEX(&cinergyt2->sem);
+
+ cinergyt2->udev = interface_to_usbdev(intf);
+
+ if (cinergyt2_alloc_stream_urbs (cinergyt2) < 0) {
+ dprintk(1, "unable to allocate stream urbs\n");
+ kfree(cinergyt2);
+ return -ENOMEM;
+ }
+
+ dvb_register_adapter(&cinergyt2->adapter, DRIVER_NAME, THIS_MODULE);
+
+ cinergyt2->demux.priv = cinergyt2;
+ cinergyt2->demux.filternum = 256;
+ cinergyt2->demux.feednum = 256;
+ cinergyt2->demux.start_feed = cinergyt2_start_feed;
+ cinergyt2->demux.stop_feed = cinergyt2_stop_feed;
+ cinergyt2->demux.dmx.capabilities = DMX_TS_FILTERING |
+ DMX_SECTION_FILTERING |
+ DMX_MEMORY_BASED_FILTERING;
+
+ if ((err = dvb_dmx_init(&cinergyt2->demux)) < 0) {
+ dprintk(1, "dvb_dmx_init() failed (err = %d)\n", err);
+ goto bailout;
+ }
+
+ cinergyt2->dmxdev.filternum = cinergyt2->demux.filternum;
+ cinergyt2->dmxdev.demux = &cinergyt2->demux.dmx;
+ cinergyt2->dmxdev.capabilities = 0;
+
+ if ((err = dvb_dmxdev_init(&cinergyt2->dmxdev, cinergyt2->adapter)) < 0) {
+ dprintk(1, "dvb_dmxdev_init() failed (err = %d)\n", err);
+ goto bailout;
+ }
+
+ if (dvb_net_init(cinergyt2->adapter, &cinergyt2->dvbnet, &cinergyt2->demux.dmx))
+ dprintk(1, "dvb_net_init() failed!\n");
+
+ dvb_register_device(cinergyt2->adapter, &cinergyt2->fedev,
+ &cinergyt2_fe_template, cinergyt2,
+ DVB_DEVICE_FRONTEND);
+
+#ifdef ENABLE_RC
+ init_input_dev(&cinergyt2->rc_input_dev);
+
+ cinergyt2->rc_input_dev.evbit[0] = BIT(EV_KEY);
+ cinergyt2->rc_input_dev.keycodesize = sizeof(unsigned char);
+ cinergyt2->rc_input_dev.keycodemax = KEY_MAX;
+ cinergyt2->rc_input_dev.name = DRIVER_NAME " remote control";
+ cinergyt2->rc_input_dev.id.bustype = BUS_USB;
+ cinergyt2->rc_input_dev.id.vendor = 0x0001;
+ cinergyt2->rc_input_dev.id.product = 0x0001;
+ cinergyt2->rc_input_dev.id.version = 0x0100;
+
+ for (i=0; i<sizeof(rc_keys)/sizeof(rc_keys[0]); i+=3)
+ set_bit(rc_keys[i+2], cinergyt2->rc_input_dev.keybit);
+
+ input_register_device(&cinergyt2->rc_input_dev);
+
+ cinergyt2->rc_input_event = KEY_MAX;
+
+ INIT_WORK(&cinergyt2->rc_query_work, cinergyt2_query_rc, cinergyt2);
+ schedule_delayed_work(&cinergyt2->rc_query_work, HZ);
+#endif
+
+ return 0;
+
+bailout:
+ dvb_dmxdev_release(&cinergyt2->dmxdev);
+ dvb_dmx_release(&cinergyt2->demux);
+ dvb_unregister_adapter (cinergyt2->adapter);
+ cinergyt2_free_stream_urbs (cinergyt2);
+ kfree(cinergyt2);
+ return -ENOMEM;
+}
+
+static void cinergyt2_disconnect (struct usb_interface *intf)
+{
+ struct cinergyt2 *cinergyt2 = usb_get_intfdata (intf);
+
+#ifdef ENABLE_RC
+ cancel_delayed_work(&cinergyt2->rc_query_work);
+ flush_scheduled_work();
+ input_unregister_device(&cinergyt2->rc_input_dev);
+#endif
+
+ cinergyt2->demux.dmx.close(&cinergyt2->demux.dmx);
+ dvb_net_release(&cinergyt2->dvbnet);
+ dvb_dmxdev_release(&cinergyt2->dmxdev);
+ dvb_dmx_release(&cinergyt2->demux);
+
+ dvb_unregister_device(cinergyt2->fedev);
+ dvb_unregister_adapter(cinergyt2->adapter);
+
+ cinergyt2_free_stream_urbs(cinergyt2);
+ kfree(cinergyt2);
+}
+
+static const struct usb_device_id cinergyt2_table [] __devinitdata = {
+ { USB_DEVICE(0x0ccd, 0x0038) },
+ { 0 }
+};
+
+MODULE_DEVICE_TABLE(usb, cinergyt2_table);
+
+static struct usb_driver cinergyt2_driver = {
+ .owner = THIS_MODULE,
+ .name = "cinergyt2",
+ .probe = cinergyt2_probe,
+ .disconnect = cinergyt2_disconnect,
+ .id_table = cinergyt2_table
+};
+
+static int __init cinergyt2_init (void)
+{
+ int err;
+
+ if ((err = usb_register(&cinergyt2_driver)) < 0) {
+ dprintk(1, "usb_register() failed! (err %i)\n", err);
+ return err;
+ }
+
+ return 0;
+}
+
+static void __exit cinergyt2_exit (void)
+{
+ usb_deregister(&cinergyt2_driver);
+}
+
+module_init (cinergyt2_init);
+module_exit (cinergyt2_exit);
+
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Holger Waechtler, Daniel Mack");
+


Attachments:
03-dvb-add-cinergy-t2.diff (25.88 kB)

2004-10-27 10:14:29

by Michael Hunold

[permalink] [raw]
Subject: [PATCH][4/5] DVB: revamp dibusb driver

- [DVB] dibusb: update documentation for the dibusb DVB driver
- [DVB] dibusb: major overhaul of the driver, including adding new vendor and product ids from clones

Signed-off-by: Michael Hunold <[email protected]>

diff -uraNwB linux-2.6.10-rc1/Documentation/dvb/README.dibusb linux-2.6.10-rc1-patched/Documentation/dvb/README.dibusb
--- linux-2.6.10-rc1/Documentation/dvb/README.dibusb 2004-10-25 14:03:49.000000000 +0200
+++ linux-2.6.10-rc1-patched/Documentation/dvb/README.dibusb 2004-09-28 21:36:44.000000000 +0200
@@ -1,9 +1,11 @@
+
+
Documentation for dib3000mb frontend driver and dibusb device driver

The drivers should work with

- Twinhan VisionPlus VisionDTV USB-Ter DVB-T Device (VP7041)
- http://www.twinhan.com/visiontv-2_4.htm
+ http://www.twinhan.com/

- CTS Portable (Chinese Television System)
http://www.2cts.tv/ctsportable/
@@ -19,6 +21,10 @@
- Ultima Electronic/Artec T1 USB TVBOX
http://www.arteceuro.com/products-tvbox.html

+- Compro Videomate DVB-U2000 - DVB-T USB
+ http://www.comprousa.com/products/vmu2000.htm
+
+- Unknown USB DVB-T device with vendor ID Hyper-Paltek

Copyright (C) 2004 Patrick Boettcher ([email protected]),

@@ -32,6 +38,11 @@


NEWS:
+ 2004-09-28 - added support for a new device (Unkown, vendor ID is Hyper-Paltek)
+ 2004-09-20 - added support for a new device (Compro DVB-U2000), thanks
+ to Amaury Demol for reporting
+ - changed usb TS transfer method (several urbs, stopping transfer
+ before setting a new pid)
2004-09-13 - added support for a new device (Artec T1 USB TVBOX), thanks
to Christian Motschke for reporting
2004-09-05 - released the dibusb device and dib3000mb-frontend driver
@@ -85,8 +96,13 @@

If you want to enable debug output, you have to load the driver manually.

-modprobe dvb-dibusb debug=1
-modprobe dib3000mb debug=1
+first have a look, which debug level are available:
+
+modinfo dvb-dibusb
+modinfo dib3000mb
+
+modprobe dvb-dibusb debug=<level>
+modprobe dib3000mb debug=<level>

should do the trick.

@@ -102,11 +118,13 @@
2. Known problems and bugs

TODO:
-- add some additional URBs for USB data transfer
-- due a firmware problem i2c writes during mpeg transfers destroy the stream
- no i2c writes during streaming, interrupt streaming, when adding another pid
+- remote control tasklet
+- signal-quality and strength calculations
+- debug messages restructure
+- i2c address probing
+-

-2.1. Adding new devices
+2.1. Adding support for devices

It is not possible to determine the range of devices based on the DiBcom
reference design. This is because the reference design of DiBcom can be sold
@@ -122,7 +140,7 @@
others.

If you are familar with C you can also add the VID and PID of the device to
-the dvb-dibusb.[hc]-files and create a patch and send it over to me or to
+the dvb-dibusb.h-file and create a patch and send it over to me or to
the linux-dvb mailing list, _after_ you have tried compiling and modprobing
it.

diff -uraNwB linux-2.6.10-rc1/drivers/media/dvb/dibusb/Kconfig linux-2.6.10-rc1-patched/drivers/media/dvb/dibusb/Kconfig
--- linux-2.6.10-rc1/drivers/media/dvb/dibusb/Kconfig 2004-10-25 14:07:53.000000000 +0200
+++ linux-2.6.10-rc1-patched/drivers/media/dvb/dibusb/Kconfig 2004-09-30 23:29:28.000000000 +0200
@@ -1,5 +1,5 @@
config DVB_DIBUSB
- tristate "Twinhan/KWorld/Hama/Artec USB DVB-T devices"
+ tristate "DiBcom/Twinhan/KWorld/Hama/Artec/Compro USB DVB-T devices"
depends on DVB_CORE && USB
select FW_LOADER
help
@@ -8,11 +8,13 @@

Devices supported by this driver:

- Twinhan VisionPlus VisionDTV USB-Ter (VP7041)
+ TwinhanDTV USB-Ter (VP7041)
+ 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

The VP7041 seems to be identical to "CTS Portable" (Chinese
Television System).
@@ -20,7 +22,7 @@
These devices can be understood as budget ones, they "only" deliver
the MPEG data.

- Currently all known copies of the DiBcom reference design have the DiBcom 3000MB
+ 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.

diff -uraNwB linux-2.6.10-rc1/drivers/media/dvb/dibusb/dvb-dibusb.c linux-2.6.10-rc1-patched/drivers/media/dvb/dibusb/dvb-dibusb.c
--- linux-2.6.10-rc1/drivers/media/dvb/dibusb/dvb-dibusb.c 2004-10-25 14:07:53.000000000 +0200
+++ linux-2.6.10-rc1-patched/drivers/media/dvb/dibusb/dvb-dibusb.c 2004-10-04 11:12:20.000000000 +0200
@@ -20,9 +20,7 @@
* Amaury Demol ([email protected]) from DiBcom for providing specs and driver
* sources, on which this driver (and the dib3000mb frontend) are based.
*
- * TODO
- * - probing for i2c addresses, it is possible, that they have been changed
- * by the vendor
+ *
*
* see Documentation/dvb/README.dibusb for more information
*/
@@ -57,7 +55,7 @@

static int debug;
module_param(debug, int, 0x644);
-MODULE_PARM_DESC(debug, "set debugging level (1=info,2=xfer,4=alotmore (|-able)).");
+MODULE_PARM_DESC(debug, "set debugging level (1=info,2=xfer,4=alotmore,8=ts,16=err (|-able)).");
#else
#define dprintk_new(args...)
#define debug_dump(b,l)
@@ -66,31 +64,14 @@
#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)

/* Version information */
#define DRIVER_VERSION "0.0"
-#define DRIVER_DESC "DiBcom based USB Budget DVB-T device"
+#define DRIVER_DESC "Driver for DiBcom based USB Budget DVB-T device"
#define DRIVER_AUTHOR "Patrick Boettcher, [email protected]"

-/* USB Driver stuff */
-
-/* table of devices that work with this driver */
-static struct usb_device_id dibusb_table [] = {
- { USB_DEVICE(USB_TWINHAN_VENDOR_ID, USB_VP7041_PRODUCT_PREFW_ID) },
- { USB_DEVICE(USB_TWINHAN_VENDOR_ID, USB_VP7041_PRODUCT_ID) },
- { USB_DEVICE(USB_IMC_NETWORKS_VENDOR_ID, USB_VP7041_PRODUCT_PREFW_ID) },
- { USB_DEVICE(USB_IMC_NETWORKS_VENDOR_ID, USB_VP7041_PRODUCT_ID) },
- { USB_DEVICE(USB_KWORLD_VENDOR_ID, USB_VSTREAM_PRODUCT_PREFW_ID) },
- { USB_DEVICE(USB_KWORLD_VENDOR_ID, USB_VSTREAM_PRODUCT_ID) },
- { USB_DEVICE(USB_DIBCOM_VENDOR_ID, USB_DIBCOM_PRODUCT_PREFW_ID) },
- { USB_DEVICE(USB_DIBCOM_VENDOR_ID, USB_DIBCOM_PRODUCT_ID) },
- { USB_DEVICE(USB_ULTIMA_ELECTRONIC_ID, USB_ULTIMA_ELEC_PROD_PREFW_ID) },
- { USB_DEVICE(USB_ULTIMA_ELECTRONIC_ID, USB_ULTIMA_ELEC_PROD_ID) },
- { } /* Terminating entry */
-};
-
-MODULE_DEVICE_TABLE (usb, dibusb_table);
-
static int dibusb_readwrite_usb(struct usb_dibusb *dib,
u8 *wbuf, u16 wlen, u8 *rbuf, u16 rlen)
{
@@ -99,12 +80,14 @@
if (wbuf == NULL || wlen == 0)
return -EINVAL;

-/* if (dib->disconnecting)
- return -EINVAL;*/
-
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]);
+
debug_dump(wbuf,wlen);

ret = usb_bulk_msg(dib->udev,COMMAND_PIPE,
@@ -189,6 +172,8 @@
(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);
}

@@ -200,11 +185,14 @@
(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,
@@ -212,25 +200,50 @@
(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);

- return dibusb_i2c_msg(dpid->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;

- if (!dib->streaming)
- return;
+ deb_xfer("urb complete feedcount: %d, status: %d\n",dib->feedcount,urb->status);

- if (urb->status == 0) {
- deb_info("URB return len: %d\n",urb->actual_length);
+ if (dib->feedcount > 0 && urb->status == 0) {
+ deb_xfer("URB return len: %d\n",urb->actual_length);
if (urb->actual_length % 188)
- deb_info("TS Packets: %d, %d\n", urb->actual_length/188,urb->actual_length % 188);
+ deb_xfer("TS Packets: %d, %d\n", urb->actual_length/188,urb->actual_length % 188);
+
+ /* 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)
dvb_dmx_swfilter_packets(&dib->demux, (u8*) urb->transfer_buffer,urb->actual_length/188);
- }
+ else
+ deb_ts("URB dropped because of the "
+ "actual_length or !dvb_is_ready (%d).\n",dib->dvb_is_ready);
+ } else
+ deb_ts("URB dropped because of feedcount or status.\n");

- if (dib->streaming)
usb_submit_urb(urb,GFP_KERNEL);
}

@@ -240,9 +253,8 @@
// struct dvb_demux *dvbdmx = dvbdmxfeed->demux;
struct usb_dibusb *dib = dvbdmxfeed->demux->priv;
struct dibusb_pid *dpid;
- int ret = 0;

- deb_info("pid: 0x%04x, feedtype: %d\n", dvbdmxfeed->pid,dvbdmxfeed->type);
+ deb_ts("pid: 0x%04x, feedtype: %d\n", dvbdmxfeed->pid,dvbdmxfeed->type);

if ((dpid = dibusb_get_free_pid(dib)) == NULL) {
err("no free pid in list.");
@@ -253,32 +265,14 @@

dibusb_set_pid(dpid);

- if (0 == dib->feed_count++) {
- usb_fill_bulk_urb( dib->buf_urb, dib->udev, DATA_PIPE,
- dib->buffer, 8192, dibusb_urb_complete, dib);
- dib->buf_urb->transfer_flags = 0;
-
-
- if ((ret = usb_submit_urb(dib->buf_urb,GFP_KERNEL))) {
- dibusb_stop_xfer(dib);
- err("could not submit buffer urb.");
- return ret;
- }
-
- if ((ret = dibusb_start_xfer(dib)))
- return ret;
-
- dib->streaming = 1;
- }
return 0;
}

static int dibusb_stop_feed(struct dvb_demux_feed *dvbdmxfeed)
{
- struct usb_dibusb *dib = dvbdmxfeed->demux->priv;
struct dibusb_pid *dpid = (struct dibusb_pid *) dvbdmxfeed->priv;

- deb_info("stopfeed pid: 0x%04x, feedtype: %d",dvbdmxfeed->pid, dvbdmxfeed->type);
+ deb_ts("stopfeed pid: 0x%04x, feedtype: %d\n",dvbdmxfeed->pid, dvbdmxfeed->type);

if (dpid == NULL)
err("channel in dmxfeed->priv was NULL");
@@ -288,11 +282,6 @@
dibusb_set_pid(dpid);
}

- if (--dib->feed_count == 0) {
- dib->streaming = 0;
- usb_unlink_urb(dib->buf_urb);
- dibusb_stop_xfer(dib);
- }
return 0;
}

@@ -302,7 +291,7 @@

/*
* do not use this, just a workaround for a bug,
- * which will never occur :).
+ * which will hopefully never occur :).
*/
static int dibusb_interrupt_read_loop(struct usb_dibusb *dib)
{
@@ -312,7 +301,8 @@

/*
* TODO: a tasklet should run with a delay of 1/10 second
- * and fill an appropriate event device ?
+ * and feed an appropriate event device ?
+ * NEC protocol is used for remote controlls
*/
static int dibusb_read_remote_control(struct usb_dibusb *dib)
{
@@ -321,6 +311,18 @@
if ((ret = dibusb_readwrite_usb(dib,b,1,rb,5)))
return ret;

+
+
+ switch (rb[0]) {
+ case DIBUSB_RC_NEC_KEY_PRESSED:
+
+ break;
+ case DIBUSB_RC_NEC_EMPTY:
+ case DIBUSB_RC_NEC_KEY_REPEATED:
+ default:
+ break;
+ }
+
return 0;
}

@@ -474,11 +476,13 @@
err:
return ret;
success:
+ dib->dvb_is_ready = 1;
return 0;
}

static int dibusb_dvb_exit(struct usb_dibusb *dib)
{
+ dib->dvb_is_ready = 0;
deb_info("unregistering DVB part\n");
dvb_net_release(&dib->dvb_net);
dib->demux.dmx.close(&dib->demux.dmx);
@@ -492,8 +496,16 @@

static int dibusb_exit(struct usb_dibusb *dib)
{
- usb_free_urb(dib->buf_urb);
- pci_free_consistent(NULL,8192,dib->buffer,dib->dma_handle);
+ 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]);
+ }
+ pci_free_consistent(NULL,DIBUSB_TS_BUFFER_SIZE,dib->buffer,dib->dma_handle);
return 0;
}

@@ -513,12 +525,28 @@

/* dibusb_reset_cpu(dib); */

- dib->buffer = pci_alloc_consistent(NULL,8192, &dib->dma_handle);
- memset(dib->buffer,0,8192);
- if (!(dib->buf_urb = usb_alloc_urb(0,GFP_KERNEL))) {
+ if ((dib->buffer = pci_alloc_consistent(NULL,DIBUSB_TS_BUFFER_SIZE, &dib->dma_handle)) == NULL) {
+ 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))) {
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,
+ dibusb_urb_complete, dib);
+ dib->buf_urb[i]->transfer_flags = 0;
+
+ if ((ret = usb_submit_urb(dib->buf_urb[i],GFP_KERNEL))) {
+ err("could not submit buffer urb no. %d\n",i);
+ dibusb_exit(dib);
+ return ret;
+ }
+ }

for (i=0; i < DIBUSB_MAX_PIDS; i++) {
dib->pid_list[i].reg = i+DIB3000MB_REG_FIRST_PID;
@@ -527,8 +555,9 @@
dib->pid_list[i].dib = dib;
}

+ dib->feedcount = 0;
dib->streaming = 0;
- dib->feed_count = 0;
+ dib->dvb_is_ready = 0;

if ((ret = dibusb_dvb_init(dib))) {
dibusb_exit(dib);
@@ -591,19 +620,23 @@
if (ret != b[0]) {
err("error while transferring firmware "
"(transferred size: %d, block size: %d)",
- ret,b[1]);
+ ret,b[0]);
ret = -EINVAL;
break;
}
i += 5 + b[0];
}
+ /* length in ret */
+ if (ret > 0)
+ ret = 0;
/* restart the CPU */
reset = 0;
- if ((ret = dibusb_writemem(udev,DIBUSB_CPU_CSREG,&reset,1)) != 1)
+ if (ret || dibusb_writemem(udev,DIBUSB_CPU_CSREG,&reset,1) != 1) {
err("could not restart the USB controller CPU.");
+ ret = -EINVAL;
+ }

kfree(p);
- ret = 0;
} else {
ret = -ENOMEM;
}
diff -uraNwB linux-2.6.10-rc1/drivers/media/dvb/dibusb/dvb-dibusb.h linux-2.6.10-rc1-patched/drivers/media/dvb/dibusb/dvb-dibusb.h
--- linux-2.6.10-rc1/drivers/media/dvb/dibusb/dvb-dibusb.h 2004-10-25 14:07:53.000000000 +0200
+++ linux-2.6.10-rc1-patched/drivers/media/dvb/dibusb/dvb-dibusb.h 2004-09-30 23:29:28.000000000 +0200
@@ -7,6 +7,7 @@
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation, version 2.
*
+ *
*
* for more information see dvb-dibusb.c .
*/
@@ -14,24 +15,102 @@
#ifndef __DVB_DIBUSB_H__
#define __DVB_DIBUSB_H__

+#define DIBUSB_DEMOD_I2C_ADDR_DEFAULT 0x10
+
/* Vendor IDs */
-#define USB_TWINHAN_VENDOR_ID 0x1822
-#define USB_IMC_NETWORKS_VENDOR_ID 0x13d3
-#define USB_KWORLD_VENDOR_ID 0xeb1a
-#define USB_DIBCOM_VENDOR_ID 0x10b8
-#define USB_ULTIMA_ELECTRONIC_ID 0x05d8
+#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

/* Product IDs before loading the firmware */
-#define USB_VP7041_PRODUCT_PREFW_ID 0x3201
-#define USB_VSTREAM_PRODUCT_PREFW_ID 0x17de
-#define USB_DIBCOM_PRODUCT_PREFW_ID 0x0bb8
-#define USB_ULTIMA_ELEC_PROD_PREFW_ID 0x8105
+#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_VP7041_PRODUCT_ID 0x3202
-#define USB_VSTREAM_PRODUCT_ID 0x17df
-#define USB_DIBCOM_PRODUCT_ID 0x0bb9
-#define USB_ULTIMA_ELEC_PROD_ID 0x8106
+#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",
+};
+
+struct dibusb_device {
+ u16 cold_product_id;
+ u16 warm_product_id;
+ u8 demod_addr;
+ const char *name;
+};
+
+#define DIBUSB_SUPPORTED_DEVICES 6
+
+/* 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,
+ },
+ { .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,
+ },
+ { .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,
+ },
+ { .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,
+ },
+ { .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,
+ },
+ { .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,
+ }
+};
+
+/* 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) },
+ { } /* Terminating entry */
+};
+
+MODULE_DEVICE_TABLE (usb, dibusb_table);

/* CS register start/stop the usb controller cpu */
#define DIBUSB_CPU_CSREG 0x7F92
@@ -53,15 +132,20 @@
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)
+
struct usb_dibusb {
/* usb */
struct usb_device * udev;

struct dibusb_device * dibdev;

+ int feedcount;
int streaming;
- int feed_count;
- struct urb *buf_urb;
+ struct urb * buf_urb[DIBUSB_TS_NUM_URBS];
u8 *buffer;
dma_addr_t dma_handle;

@@ -77,52 +161,13 @@
struct semaphore i2c_sem;

/* dvb */
+ int dvb_is_ready;
struct dvb_adapter *adapter;
struct dmxdev dmxdev;
struct dvb_demux demux;
struct dvb_net dvb_net;
};

-
-struct dibusb_device {
- u16 cold_product_id;
- u16 warm_product_id;
- u8 demod_addr;
- const char *name;
-};
-
-/* static array of valid firmware names, the best one first */
-static const char * valid_firmware_filenames[] = {
- "dvb-dibusb-5.0.0.11.fw",
-};
-
-#define DIBUSB_SUPPORTED_DEVICES 4
-
-/* USB Driver stuff */
-static struct dibusb_device dibusb_devices[DIBUSB_SUPPORTED_DEVICES] = {
- { .cold_product_id = USB_VP7041_PRODUCT_PREFW_ID,
- .warm_product_id = USB_VP7041_PRODUCT_ID,
- .name = "Twinhan VisionDTV USB-Ter/HAMA USB DVB-T device",
- .demod_addr = DIBUSB_DEMOD_I2C_ADDR_DEFAULT,
- },
- { .cold_product_id = USB_VSTREAM_PRODUCT_PREFW_ID,
- .warm_product_id = USB_VSTREAM_PRODUCT_ID,
- .name = "KWorld V-Stream XPERT DTV - DVB-T USB",
- .demod_addr = DIBUSB_DEMOD_I2C_ADDR_DEFAULT,
- },
- { .cold_product_id = USB_DIBCOM_PRODUCT_PREFW_ID,
- .warm_product_id = USB_DIBCOM_PRODUCT_ID,
- .name = "DiBcom USB reference design",
- .demod_addr = DIBUSB_DEMOD_I2C_ADDR_DEFAULT,
- },
- {
- .cold_product_id = USB_ULTIMA_ELEC_PROD_PREFW_ID,
- .warm_product_id = USB_ULTIMA_ELEC_PROD_ID,
- .name = "Ultima Electronic/Artec T1 USB TVBOX",
- .demod_addr = DIBUSB_DEMOD_I2C_ADDR_DEFAULT,
- },
-};
-
#define COMMAND_PIPE usb_sndbulkpipe(dib->udev, 0x01)
#define RESULT_PIPE usb_rcvbulkpipe(dib->udev, 0x81)
#define DATA_PIPE usb_rcvbulkpipe(dib->udev, 0x82)
@@ -142,6 +187,10 @@
/* prefix for reading the current RC key */
#define DIBUSB_REQ_POLL_REMOTE 0x04

+#define DIBUSB_RC_NEC_EMPTY 0x00
+#define DIBUSB_RC_NEC_KEY_PRESSED 0x01
+#define DIBUSB_RC_NEC_KEY_REPEATED 0x02
+
/* 0x05 0xXX */
#define DIBUSB_REQ_SET_STREAMING_MODE 0x05

diff -uraNwB linux-2.6.10-rc1/drivers/media/dvb/frontends/dib3000mb.c linux-2.6.10-rc1-patched/drivers/media/dvb/frontends/dib3000mb.c
--- linux-2.6.10-rc1/drivers/media/dvb/frontends/dib3000mb.c 2004-10-25 14:07:55.000000000 +0200
+++ linux-2.6.10-rc1-patched/drivers/media/dvb/frontends/dib3000mb.c 2004-10-13 21:36:12.000000000 +0200
@@ -17,6 +17,8 @@
* Amaury Demol ([email protected]) from DiBcom for providing specs and driver
* sources, on which this driver (and the dvb-dibusb) are based.
*
+ *
+ *
* see Documentation/dvb/README.dibusb for more information
*
*/
@@ -36,19 +38,21 @@
/* debug */

#ifdef CONFIG_DVB_DIBCOM_DEBUG
-#define dprintk_new(level,args...) \
+#define dprintk(level,args...) \
do { if ((debug & level)) { printk(args); } } while (0)

static int debug;
module_param(debug, int, 0x644);
-MODULE_PARM_DESC(debug, "set debugging level (1=info,2=xfer,4=alotmore (|-able)).");
+MODULE_PARM_DESC(debug, "set debugging level (1=info,2=xfer,4=alotmore,8=setfe,16=getfe (|-able)).");
#else
-#define dprintk_new(args...)
+#define dprintk(args...) do { } while (0);
#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_info(args...) dprintk(0x01,args)
+#define deb_xfer(args...) dprintk(0x02,args)
+#define deb_alot(args...) dprintk(0x04,args)
+#define deb_setf(args...) dprintk(0x08,args)
+#define deb_getf(args...) dprintk(0x10,args)

/* Version information */
#define DRIVER_VERSION "0.1"
@@ -63,7 +67,7 @@
};

static struct dvb_frontend_info dib3000mb_info = {
- .name = "DiBcom 3000-MB DVB-T frontend",
+ .name = "DiBcom 3000-MB DVB-T",
.type = FE_OFDM,
.frequency_min = 44250000,
.frequency_max = 867250000,
@@ -72,8 +76,8 @@
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_QPSK | FE_CAN_QAM_16 | FE_CAN_QAM_64 | FE_CAN_QAM_AUTO |
- FE_CAN_TRANSMISSION_MODE_AUTO |
FE_CAN_GUARD_INTERVAL_AUTO |
+ FE_CAN_TRANSMISSION_MODE_AUTO |
FE_CAN_HIERARCHY_AUTO,
};

@@ -149,7 +153,7 @@
u32 dds_val, threshold = 0x800000;

if (!rd(DIB3000MB_REG_TPS_LOCK))
- return -EINVAL;
+ return 0;

dds_val = ((rd(DIB3000MB_REG_DDS_VALUE_MSB) & 0xff) << 16) + rd(DIB3000MB_REG_DDS_VALUE_LSB);
if (dds_val & threshold)
@@ -172,56 +176,56 @@
||
((inv_test2 == 0) && (inv_test1==1 || inv_test1==2));

- deb_info("inversion %d %d, %d\n",inv_test2,inv_test1, fep->inversion);
+ deb_getf("inversion %d %d, %d\n",inv_test2,inv_test1, fep->inversion);

switch ((tps_val = rd(DIB3000MB_REG_TPS_QAM))) {
case DIB3000MB_QAM_QPSK:
- deb_info("QPSK ");
+ deb_getf("QPSK ");
ofdm->constellation = QPSK;
break;
case DIB3000MB_QAM_QAM16:
- deb_info("QAM16 ");
+ deb_getf("QAM16 ");
ofdm->constellation = QAM_16;
break;
case DIB3000MB_QAM_QAM64:
- deb_info("QAM64 ");
+ deb_getf("QAM64 ");
ofdm->constellation = QAM_64;
break;
default:
err("Unexpected constellation returned by TPS (%d)",tps_val);
break;
}
- deb_info("TPS: %d\n",tps_val);
+ deb_getf("TPS: %d\n",tps_val);

if (rd(DIB3000MB_REG_TPS_HRCH)) {
- deb_info("HRCH ON\n");
+ deb_getf("HRCH ON\n");
tps_val = rd(DIB3000MB_REG_TPS_CODE_RATE_LP);
cr = &ofdm->code_rate_LP;
ofdm->code_rate_HP = FEC_NONE;

switch ((tps_val = rd(DIB3000MB_REG_TPS_VIT_ALPHA))) {
case DIB3000MB_VIT_ALPHA_OFF:
- deb_info("HIERARCHY_NONE ");
+ deb_getf("HIERARCHY_NONE ");
ofdm->hierarchy_information = HIERARCHY_NONE;
break;
case DIB3000MB_VIT_ALPHA_1:
- deb_info("HIERARCHY_1 ");
+ deb_getf("HIERARCHY_1 ");
ofdm->hierarchy_information = HIERARCHY_1;
break;
case DIB3000MB_VIT_ALPHA_2:
- deb_info("HIERARCHY_2 ");
+ deb_getf("HIERARCHY_2 ");
ofdm->hierarchy_information = HIERARCHY_2;
break;
case DIB3000MB_VIT_ALPHA_4:
- deb_info("HIERARCHY_4 ");
+ deb_getf("HIERARCHY_4 ");
ofdm->hierarchy_information = HIERARCHY_4;
break;
default:
err("Unexpected ALPHA value returned by TPS (%d)",tps_val);
}
- deb_info("TPS: %d\n",tps_val);
+ deb_getf("TPS: %d\n",tps_val);
} else {
- deb_info("HRCH OFF\n");
+ deb_getf("HRCH OFF\n");
tps_val = rd(DIB3000MB_REG_TPS_CODE_RATE_HP);
cr = &ofdm->code_rate_HP;
ofdm->code_rate_LP = FEC_NONE;
@@ -230,67 +234,67 @@

switch (tps_val) {
case DIB3000MB_FEC_1_2:
- deb_info("FEC_1_2 ");
+ deb_getf("FEC_1_2 ");
*cr = FEC_1_2;
break;
case DIB3000MB_FEC_2_3:
- deb_info("FEC_2_3 ");
+ deb_getf("FEC_2_3 ");
*cr = FEC_2_3;
break;
case DIB3000MB_FEC_3_4:
- deb_info("FEC_3_4 ");
+ deb_getf("FEC_3_4 ");
*cr = FEC_3_4;
break;
case DIB3000MB_FEC_5_6:
- deb_info("FEC_5_6 ");
+ deb_getf("FEC_5_6 ");
*cr = FEC_4_5;
break;
case DIB3000MB_FEC_7_8:
- deb_info("FEC_7_8 ");
+ deb_getf("FEC_7_8 ");
*cr = FEC_7_8;
break;
default:
err("Unexpected FEC returned by TPS (%d)",tps_val);
break;
}
- deb_info("TPS: %d\n",tps_val);
+ deb_getf("TPS: %d\n",tps_val);

switch ((tps_val = rd(DIB3000MB_REG_TPS_GUARD_TIME))) {
case DIB3000MB_GUARD_TIME_1_32:
- deb_info("GUARD_INTERVAL_1_32 ");
+ deb_getf("GUARD_INTERVAL_1_32 ");
ofdm->guard_interval = GUARD_INTERVAL_1_32;
break;
case DIB3000MB_GUARD_TIME_1_16:
- deb_info("GUARD_INTERVAL_1_16 ");
+ deb_getf("GUARD_INTERVAL_1_16 ");
ofdm->guard_interval = GUARD_INTERVAL_1_16;
break;
case DIB3000MB_GUARD_TIME_1_8:
- deb_info("GUARD_INTERVAL_1_8 ");
+ deb_getf("GUARD_INTERVAL_1_8 ");
ofdm->guard_interval = GUARD_INTERVAL_1_8;
break;
case DIB3000MB_GUARD_TIME_1_4:
- deb_info("GUARD_INTERVAL_1_4 ");
+ deb_getf("GUARD_INTERVAL_1_4 ");
ofdm->guard_interval = GUARD_INTERVAL_1_4;
break;
default:
err("Unexpected Guard Time returned by TPS (%d)",tps_val);
break;
}
- deb_info("TPS: %d\n",tps_val);
+ deb_getf("TPS: %d\n",tps_val);

switch ((tps_val = rd(DIB3000MB_REG_TPS_FFT))) {
case DIB3000MB_FFT_2K:
- deb_info("TRANSMISSION_MODE_2K ");
+ deb_getf("TRANSMISSION_MODE_2K ");
ofdm->transmission_mode = TRANSMISSION_MODE_2K;
break;
case DIB3000MB_FFT_8K:
- deb_info("TRANSMISSION_MODE_8K ");
+ deb_getf("TRANSMISSION_MODE_8K ");
ofdm->transmission_mode = TRANSMISSION_MODE_8K;
break;
default:
err("unexpected transmission mode return by TPS (%d)",tps_val);
}
- deb_info("TPS: %d\n",tps_val);
+ deb_getf("TPS: %d\n",tps_val);
return 0;
}

@@ -307,18 +311,18 @@
if (irq & 0x02) {
if (rd(DIB3000MB_REG_LOCK2_VALUE) & 0x01) {
if (dib3000mb_get_frontend(state,&fep) == 0) {
- deb_info("reading tuning data from frontend succeeded.\n");
+ deb_setf("reading tuning data from frontend succeeded.\n");
return dib3000mb_set_frontend(state,&fep,0) == 0;
} else {
- deb_info("reading tuning data failed -> tuning failed.\n");
+ deb_setf("reading tuning data failed -> tuning failed.\n");
return 0;
}
} else {
- deb_info("AS IRQ was pending, but LOCK2 was not & 0x01.\n");
+ deb_setf("AS IRQ was pending, but LOCK2 was not & 0x01.\n");
return 0;
}
} else if (irq & 0x01) {
- deb_info("Autosearch failed.\n");
+ deb_setf("Autosearch failed.\n");
return 0;
}

@@ -329,7 +333,7 @@
struct dvb_frontend_parameters *fep, int tuner)
{
struct dvb_ofdm_parameters *ofdm = &fep->u.ofdm;
- fe_code_rate_t fe_cr;
+ fe_code_rate_t fe_cr = FEC_NONE;
int search_state,seq;

if (tuner) {
@@ -342,82 +346,105 @@
wr(DIB3000MB_REG_TUNER,
DIB3000MB_DEACTIVATE_TUNER_XFER( DIB3000MB_TUNER_ADDR_DEFAULT ) );

+ deb_setf("bandwidth: ");
switch (ofdm->bandwidth) {
case BANDWIDTH_8_MHZ:
- case BANDWIDTH_AUTO:
+ deb_setf("8 MHz\n");
wr_foreach(dib3000mb_reg_timing_freq,dib3000mb_timing_freq[2]);
wr_foreach(dib3000mb_reg_bandwidth,dib3000mb_bandwidth_8mhz);
break;
case BANDWIDTH_7_MHZ:
+ deb_setf("7 MHz\n");
wr_foreach(dib3000mb_reg_timing_freq,dib3000mb_timing_freq[1]);
wr_foreach(dib3000mb_reg_bandwidth,dib3000mb_bandwidth_7mhz);
break;
case BANDWIDTH_6_MHZ:
+ deb_setf("6 MHz\n");
wr_foreach(dib3000mb_reg_timing_freq,dib3000mb_timing_freq[0]);
wr_foreach(dib3000mb_reg_bandwidth,dib3000mb_bandwidth_6mhz);
break;
+ case BANDWIDTH_AUTO:
+ return -EOPNOTSUPP;
default:
err("unkown bandwidth value.");
return -EINVAL;
- break;
}
}
wr(DIB3000MB_REG_LOCK1_MASK,DIB3000MB_LOCK1_SEARCH_4);

+ deb_setf("transmission mode: ");
switch (ofdm->transmission_mode) {
case TRANSMISSION_MODE_2K:
+ deb_setf("2k\n");
wr(DIB3000MB_REG_FFT,DIB3000MB_FFT_2K);
break;
case TRANSMISSION_MODE_8K:
+ deb_setf("8k\n");
wr(DIB3000MB_REG_FFT,DIB3000MB_FFT_8K);
break;
case TRANSMISSION_MODE_AUTO:
+ deb_setf("auto\n");
wr(DIB3000MB_REG_FFT,DIB3000MB_FFT_AUTO);
break;
default:
return -EINVAL;
}

+ deb_setf("guard: ");
switch (ofdm->guard_interval) {
case GUARD_INTERVAL_1_32:
+ deb_setf("1_32\n");
wr(DIB3000MB_REG_GUARD_TIME,DIB3000MB_GUARD_TIME_1_32);
break;
case GUARD_INTERVAL_1_16:
+ deb_setf("1_16\n");
wr(DIB3000MB_REG_GUARD_TIME,DIB3000MB_GUARD_TIME_1_16);
break;
case GUARD_INTERVAL_1_8:
+ deb_setf("1_8\n");
wr(DIB3000MB_REG_GUARD_TIME,DIB3000MB_GUARD_TIME_1_8);
break;
case GUARD_INTERVAL_1_4:
+ deb_setf("1_4\n");
wr(DIB3000MB_REG_GUARD_TIME,DIB3000MB_GUARD_TIME_1_4);
break;
case GUARD_INTERVAL_AUTO:
+ deb_setf("auto\n");
wr(DIB3000MB_REG_GUARD_TIME,DIB3000MB_GUARD_TIME_AUTO);
break;
default:
return -EINVAL;
}

+ deb_setf("invsersion: ");
switch (fep->inversion) {
+ case INVERSION_AUTO:
+ deb_setf("auto\n");
+ break;
case INVERSION_OFF:
+ deb_setf("on\n");
wr(DIB3000MB_REG_DDS_INV,DIB3000MB_DDS_INV_OFF);
break;
- case INVERSION_AUTO:
case INVERSION_ON:
+ deb_setf("on\n");
wr(DIB3000MB_REG_DDS_INV,DIB3000MB_DDS_INV_ON);
break;
default:
return -EINVAL;
}

+ deb_setf("constellation: ");
switch (ofdm->constellation) {
case QPSK:
+ deb_setf("qpsk\n");
wr(DIB3000MB_REG_QAM,DIB3000MB_QAM_QPSK);
break;
case QAM_16:
+ deb_setf("qam16\n");
wr(DIB3000MB_REG_QAM,DIB3000MB_QAM_QAM16);
break;
case QAM_64:
+ deb_setf("qam64\n");
wr(DIB3000MB_REG_QAM,DIB3000MB_QAM_QAM64);
break;
case QAM_AUTO:
@@ -425,53 +452,69 @@
default:
return -EINVAL;
}
-
+ deb_setf("hierachy: ");
switch (ofdm->hierarchy_information) {
case HIERARCHY_NONE:
+ deb_setf("none ");
+ /* fall through alpha is 1, even when HIERARCHY is NONE */
case HIERARCHY_1:
+ deb_setf("alpha=1\n");
wr(DIB3000MB_REG_VIT_ALPHA,DIB3000MB_VIT_ALPHA_1);
break;
case HIERARCHY_2:
+ deb_setf("alpha=2\n");
wr(DIB3000MB_REG_VIT_ALPHA,DIB3000MB_VIT_ALPHA_2);
break;
case HIERARCHY_4:
+ deb_setf("alpha=4\n");
wr(DIB3000MB_REG_VIT_ALPHA,DIB3000MB_VIT_ALPHA_4);
break;
case HIERARCHY_AUTO:
+ deb_setf("alpha=auto\n");
wr(DIB3000MB_REG_VIT_ALPHA,DIB3000MB_VIT_ALPHA_AUTO);
break;
default:
return -EINVAL;
}

+ deb_setf("hierarchy: ");
if (ofdm->hierarchy_information == HIERARCHY_NONE) {
+ deb_setf("none\n");
wr(DIB3000MB_REG_VIT_HRCH,DIB3000MB_VIT_HRCH_OFF);
wr(DIB3000MB_REG_VIT_HP,DIB3000MB_VIT_HP);
fe_cr = ofdm->code_rate_HP;
- } else {
+ } else if (ofdm->hierarchy_information != HIERARCHY_AUTO) {
+ deb_setf("on\n");
wr(DIB3000MB_REG_VIT_HRCH,DIB3000MB_VIT_HRCH_ON);
wr(DIB3000MB_REG_VIT_HP,DIB3000MB_VIT_LP);
fe_cr = ofdm->code_rate_LP;
}
-
+ deb_setf("fec: ");
switch (fe_cr) {
case FEC_1_2:
+ deb_setf("1_2\n");
wr(DIB3000MB_REG_VIT_CODE_RATE,DIB3000MB_FEC_1_2);
break;
case FEC_2_3:
+ deb_setf("2_3\n");
wr(DIB3000MB_REG_VIT_CODE_RATE,DIB3000MB_FEC_2_3);
break;
case FEC_3_4:
+ deb_setf("3_4\n");
wr(DIB3000MB_REG_VIT_CODE_RATE,DIB3000MB_FEC_3_4);
break;
case FEC_5_6:
+ deb_setf("5_6\n");
wr(DIB3000MB_REG_VIT_CODE_RATE,DIB3000MB_FEC_5_6);
break;
case FEC_7_8:
+ deb_setf("7_8\n");
wr(DIB3000MB_REG_VIT_CODE_RATE,DIB3000MB_FEC_7_8);
break;
case FEC_NONE:
+ deb_setf("none ");
case FEC_AUTO:
+ deb_setf("auto\n");
break;
default:
return -EINVAL;
@@ -482,7 +525,7 @@
[ofdm->guard_interval == GUARD_INTERVAL_AUTO]
[fep->inversion == INVERSION_AUTO];

- deb_info("seq? %d\n",seq);
+ deb_setf("seq? %d\n",seq);

wr(DIB3000MB_REG_SEQ,seq);

@@ -522,7 +565,7 @@
fe_cr == FEC_AUTO ||
fep->inversion == INVERSION_AUTO) {

- deb_info("autosearch enabled.\n");
+ deb_setf("autosearch enabled.\n");

wr(DIB3000MB_REG_ISI,DIB3000MB_ISI_INHIBIT);

@@ -530,7 +573,7 @@
wr(DIB3000MB_REG_RESTART,DIB3000MB_RESTART_OFF);

while ((search_state = dib3000mb_fe_read_search_status(state)) < 0);
-
+ deb_info("search_state after autosearch %d\n",search_state);
return search_state ? 0 : -EINVAL;
} else {
wr(DIB3000MB_REG_RESTART,DIB3000MB_RESTART_CTRL);
@@ -622,14 +665,25 @@
static int dib3000mb_read_status(struct dib3000mb_state *state,fe_status_t *stat)
{
*stat = 0;
- *stat |= rd(DIB3000MB_REG_AGC_LOCK) ? FE_HAS_SIGNAL : 0;
- *stat |= rd(DIB3000MB_REG_CARRIER_LOCK) ? FE_HAS_CARRIER : 0;
- *stat |= rd(DIB3000MB_REG_VIT_LCK) ? FE_HAS_VITERBI : 0;
- *stat |= rd(DIB3000MB_REG_TS_SYNC_LOCK) ? FE_HAS_SYNC : 0;
- *stat |= *stat ? FE_HAS_LOCK : 0;
+
+ if (rd(DIB3000MB_REG_AGC_LOCK))
+ *stat |= FE_HAS_SIGNAL;
+ if (rd(DIB3000MB_REG_CARRIER_LOCK))
+ *stat |= FE_HAS_CARRIER;
+ if (rd(DIB3000MB_REG_VIT_LCK))
+ *stat |= FE_HAS_VITERBI;
+ if (rd(DIB3000MB_REG_TS_SYNC_LOCK))
+ *stat |= (FE_HAS_SYNC | FE_HAS_LOCK);

deb_info("actual status is %2x\n",*stat);

+ deb_getf("tps %x %x %x %x %x\n",
+ rd(DIB3000MB_REG_TPS_1),
+ rd(DIB3000MB_REG_TPS_2),
+ rd(DIB3000MB_REG_TPS_3),
+ rd(DIB3000MB_REG_TPS_4),
+ rd(DIB3000MB_REG_TPS_5));
+
deb_info("autoval: tps: %d, qam: %d, hrch: %d, alpha: %d, hp: %d, lp: %d, guard: %d, fft: %d cell: %d\n",
rd(DIB3000MB_REG_TPS_LOCK),
rd(DIB3000MB_REG_TPS_QAM),
@@ -647,15 +701,75 @@

static int dib3000mb_read_ber(struct dib3000mb_state *state,u32 *ber)
{
- *ber =
- (((rd(DIB3000MB_REG_BER_MSB) << 16) & 0x1f) | rd(DIB3000MB_REG_BER_LSB) ) /
- 100000000;
+ *ber = ((rd(DIB3000MB_REG_BER_MSB) << 16) | rd(DIB3000MB_REG_BER_LSB) );
+ return 0;
+}
+/*
+ * Amaury:
+ * signal strength is measured with dBm (power compared to mW)
+ * the standard range is -90dBm(low power) to -10 dBm (strong power),
+ * but the calibration is done for -100 dBm to 0dBm
+ */
+
+#define DIB3000MB_AGC_REF_dBm -14
+#define DIB3000MB_GAIN_SLOPE_dBm 100
+#define DIB3000MB_GAIN_DELTA_dBm -2
+static int dib3000mb_read_signal_strength(struct dib3000mb_state *state, u16 *strength)
+{
+/* TODO log10
+ u16 sigpow = rd(DIB3000MB_REG_SIGNAL_POWER),
+ n_agc_power = rd(DIB3000MB_REG_AGC_POWER),
+ rf_power = rd(DIB3000MB_REG_RF_POWER);
+ double rf_power_dBm, ad_power_dBm, minar_power_dBm;
+
+ if (n_agc_power == 0 )
+ n_agc_power = 1 ;
+
+ ad_power_dBm = 10 * log10 ( (float)n_agc_power / (float)(1<<16) );
+ minor_power_dBm = ad_power_dBm - DIB3000MB_AGC_REF_dBm;
+ rf_power_dBm = (-DIB3000MB_GAIN_SLOPE_dBm * (float)rf_power / (float)(1<<16) +
+ DIB3000MB_GAIN_DELTA_dBm) + minor_power_dBm;
+ // relative rf_power
+ *strength = (u16) ((rf_power_dBm + 100) / 100 * 0xffff);
+*/
+ *strength = rd(DIB3000MB_REG_SIGNAL_POWER) * 0xffff / 0x170;
+ return 0;
+}
+
+/*
+ * Amaury:
+ * snr is the signal quality measured in dB.
+ * snr = 10*log10(signal power / noise power)
+ * the best quality is near 35dB (cable transmission & good modulator)
+ * the minimum without errors depend of transmission parameters
+ * some indicative values are given in en300744 Annex A
+ * ex : 16QAM 2/3 (Gaussian) = 11.1 dB
+ *
+ * If SNR is above 20dB, BER should be always 0.
+ * choose 0dB as the minimum
+ */
+static int dib3000mb_read_snr(struct dib3000mb_state *state,u16 *snr)
+{
+ short sigpow = rd(DIB3000MB_REG_SIGNAL_POWER);
+ int icipow = ((rd(DIB3000MB_REG_NOISE_POWER_MSB) & 0xff) << 16) |
+ rd(DIB3000MB_REG_NOISE_POWER_LSB);
+/*
+ float snr_dBm=0;
+
+ if (sigpow > 0 && icipow > 0)
+ snr_dBm = 10.0 * log10( (float) (sigpow<<8) / (float)icipow ) ;
+ else if (sigpow > 0)
+ snr_dBm = 35;
+
+ *snr = (u16) ((snr_dBm / 35) * 0xffff);
+*/
+ *snr = (sigpow<<8) / (icipow > 0 ? icipow : 1);
return 0;
}

-static int dib3000mb_signal_strength(struct dib3000mb_state *state, u16 *strength)
+static int dib3000mb_read_unc_blocks(struct dib3000mb_state *state,u32 *unc)
{
-// *stength = DIB3000MB_REG_SIGNAL_POWER
+ *unc = rd(DIB3000MB_REG_UNC);
return 0;
}

@@ -665,63 +779,81 @@
return 0;
}

+static int dib3000mb_fe_get_tune_settings(struct dib3000mb_state *state,
+ struct dvb_frontend_tune_settings *tune)
+{
+ tune->min_delay_ms = 800;
+ tune->step_size = 166667;
+ tune->max_drift = 166667*2;
+
+ return 0;
+}
+
static int dib3000mb_ioctl (struct dvb_frontend *fe, unsigned int cmd, void *arg)
{
struct dib3000mb_state *state = fe->data;
- int ret = 0;
switch (cmd) {
case FE_GET_INFO:
deb_info("FE_GET_INFO\n");
memcpy(arg, &dib3000mb_info, sizeof(struct dvb_frontend_info));
+ return 0;
break;

case FE_READ_STATUS:
deb_info("FE_READ_STATUS\n");
- ret = dib3000mb_read_status(state,(fe_status_t *)arg);
+ return dib3000mb_read_status(state,(fe_status_t *)arg);
break;

case FE_READ_BER:
deb_info("FE_READ_BER\n");
- ret = dib3000mb_read_ber(state,(u32 *)arg);
+ return dib3000mb_read_ber(state,(u32 *)arg);
break;

case FE_READ_SIGNAL_STRENGTH:
deb_info("FE_READ_SIG_STRENGTH\n");
- ret = dib3000mb_signal_strength(state,(u16 *) arg);
+ return dib3000mb_read_signal_strength(state,(u16 *) arg);
break;

case FE_READ_SNR:
deb_info("FE_READ_SNR\n");
+ return dib3000mb_read_snr(state,(u16 *) arg);
break;

case FE_READ_UNCORRECTED_BLOCKS:
deb_info("FE_READ_UNCORRECTED_BLOCKS\n");
+ return dib3000mb_read_unc_blocks(state,(u32 *) arg);
break;

case FE_SET_FRONTEND:
deb_info("FE_SET_FRONTEND\n");
- ret = dib3000mb_set_frontend(state,(struct dvb_frontend_parameters *) arg,1);
+ return dib3000mb_set_frontend(state,(struct dvb_frontend_parameters *) arg,1);
break;

case FE_GET_FRONTEND:
deb_info("FE_GET_FRONTEND\n");
- ret = dib3000mb_get_frontend(state,(struct dvb_frontend_parameters *) arg);
+ return dib3000mb_get_frontend(state,(struct dvb_frontend_parameters *) arg);
break;

case FE_SLEEP:
deb_info("FE_SLEEP\n");
- ret = dib3000mb_sleep(state);
+ return dib3000mb_sleep(state);
break;

case FE_INIT:
deb_info("FE_INIT\n");
- ret = dib3000mb_fe_init(state,0);
+ return dib3000mb_fe_init(state,0);
break;

+ case FE_GET_TUNE_SETTINGS:
+ deb_info("GET_TUNE_SETTINGS");
+ return dib3000mb_fe_get_tune_settings(state, (struct
+ dvb_frontend_tune_settings *) arg);
+
+ break;
case FE_SET_TONE:
case FE_SET_VOLTAGE:
default:
- ret = -EOPNOTSUPP;
+ return -EOPNOTSUPP;
break;
}
return 0;
@@ -753,16 +885,20 @@
i2c_set_clientdata(client,state);

state->manufactor_id = dib3000mb_read_reg(client, DIB3000MB_REG_MANUFACTOR_ID);
+ if (state->manufactor_id != 0x01b3) {
+ ret = -ENODEV;
+ goto probe_err;
+ }
+
state->device_id = dib3000mb_read_reg(client,DIB3000MB_REG_DEVICE_ID);
- if (state->manufactor_id == 0x01b3 && state->device_id == 0x3000)
- info("found a DiBCom (0x%04x) 3000-MB DVB-T frontend (ver: %x).",
- state->manufactor_id, state->device_id);
- else {
- err("did not found a DiBCom 3000-MB.");
+ if (state->device_id != 0x3000) {
ret = -ENODEV;
goto probe_err;
}

+ info("found a DiBCom (0x%04x) 3000-MB DVB-T frontend (ver: %x).",
+ state->manufactor_id, state->device_id);
+
if ((ret = i2c_attach_client(client)))
goto i2c_attach_err;

diff -uraNwB linux-2.6.10-rc1/drivers/media/dvb/frontends/dib3000mb.h linux-2.6.10-rc1-patched/drivers/media/dvb/frontends/dib3000mb.h
--- linux-2.6.10-rc1/drivers/media/dvb/frontends/dib3000mb.h 2004-10-25 14:07:56.000000000 +0200
+++ linux-2.6.10-rc1-patched/drivers/media/dvb/frontends/dib3000mb.h 2004-09-28 21:39:06.000000000 +0200
@@ -7,6 +7,7 @@
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation, version 2.
*
+ *
*
* for more information see dib3000mb.c .
*/
@@ -320,7 +321,7 @@
#define DIB3000MB_REG_UNK_108 ( 108)
#define DIB3000MB_UNK_108 (0x0080)

-/* fft ??? */
+/* fft */
#define DIB3000MB_REG_UNK_121 ( 121)
#define DIB3000MB_UNK_121_2K ( 7)
#define DIB3000MB_UNK_121_DEFAULT ( 5)
@@ -351,12 +352,11 @@
#define DIB3000MB_REG_VIT_CODE_RATE ( 129)

/* forward error correction code rates */
-#define DIB3000MB_FEC_1_2 ( 0)
-#define DIB3000MB_FEC_2_3 ( 1)
-#define DIB3000MB_FEC_3_4 ( 2)
-#define DIB3000MB_FEC_4_5 ( 3)
-#define DIB3000MB_FEC_5_6 ( 4)
-#define DIB3000MB_FEC_7_8 ( 5)
+#define DIB3000MB_FEC_1_2 ( 1)
+#define DIB3000MB_FEC_2_3 ( 2)
+#define DIB3000MB_FEC_3_4 ( 3)
+#define DIB3000MB_FEC_5_6 ( 5)
+#define DIB3000MB_FEC_7_8 ( 7)

/* vit select hp */
#define DIB3000MB_REG_VIT_HP ( 130)
@@ -627,8 +627,8 @@
/* packet error rate (uncorrected TS packets) (16) */
#define DIB3000MB_REG_PACKET_ERROR_RATE ( 417)

-/* packet error count (16) */
-#define DIB3000MB_REG_PACKET_ERROR_COUNT ( 420)
+/* uncorrected packet count (16) */
+#define DIB3000MB_REG_UNC ( 420)

/* viterbi locked (1) */
#define DIB3000MB_REG_VIT_LCK ( 421)


Attachments:
04-dvb-dibusb-update.diff (43.28 kB)

2004-10-27 10:18:55

by Michael Hunold

[permalink] [raw]
Subject: [PATCH][5/5] DVB: misc. updates to frontend drivers

- [DVB] add legacy DishNetwork support to dvb core and stv0299, thanks to Jeremy Hall
- [DVB] mt352: major cleanup, support DVICO FusionHDTV DVB-T, thanks to Christopher Pascoe

Signed-off-by: Michael Hunold <[email protected]>

diff -uraNwB linux-2.6.10-rc1/include/linux/dvb/frontend.h linux-2.6.10-rc1-patched/include/linux/dvb/frontend.h
--- linux-2.6.10-rc1/include/linux/dvb/frontend.h 2004-10-25 14:03:20.000000000 +0200
+++ linux-2.6.10-rc1-patched/include/linux/dvb/frontend.h 2004-10-25 14:14:44.000000000 +0200
@@ -258,6 +258,8 @@
#define FE_GET_FRONTEND _IOR('o', 77, struct dvb_frontend_parameters)
#define FE_GET_EVENT _IOR('o', 78, struct dvb_frontend_event)

+#define FE_DISHNETWORK_SEND_LEGACY_CMD _IO('o', 80) /* unsigned int */
+

#endif /*_DVBFRONTEND_H_*/
diff -uraNwB linux-2.6.10-rc1/drivers/media/dvb/frontends/stv0299.c linux-2.6.10-rc1-patched/drivers/media/dvb/frontends/stv0299.c
--- linux-2.6.10-rc1/drivers/media/dvb/frontends/stv0299.c 2004-10-25 14:07:56.000000000 +0200
+++ linux-2.6.10-rc1-patched/drivers/media/dvb/frontends/stv0299.c 2004-10-25 14:14:43.000000000 +0200
@@ -885,6 +885,43 @@
}


+static int stv0299_send_legacy_dish_cmd(struct i2c_adapter *i2c, u32 cmd,
+ int tuner_type)
+{
+ u8 last = 1;
+ int i;
+
+ /* reset voltage at the end
+ if((0x50 & stv0299_readreg (i2c, 0x0c)) == 0x50)
+ cmd |= 0x80;
+ else
+ cmd &= 0x7F;
+ */
+
+ cmd = cmd << 1;
+ dprintk("%s switch command: 0x%04x\n",__FUNCTION__, cmd);
+
+ stv0299_set_voltage(i2c,SEC_VOLTAGE_18,tuner_type);
+ msleep(32);
+
+ for (i=0; i<9; i++) {
+ if((cmd & 0x01) != last) {
+ stv0299_set_voltage(i2c,
+ last ? SEC_VOLTAGE_13 :
+ SEC_VOLTAGE_18,
+ tuner_type);
+ last = (last) ? 0 : 1;
+ }
+
+ cmd = cmd >> 1;
+
+ if (i != 8)
+ msleep(8);
+ }
+
+ return 0;
+}
+
static int stv0299_set_symbolrate (struct i2c_adapter *i2c, u32 srate, int tuner_type)
{
u64 big = srate;
@@ -1229,6 +1266,10 @@
return stv0299_set_voltage (i2c, (fe_sec_voltage_t) arg,
state->tuner_type);

+ case FE_DISHNETWORK_SEND_LEGACY_CMD:
+ return stv0299_send_legacy_dish_cmd (i2c, (u32) arg,
+ state->tuner_type);
+
case FE_GET_TUNE_SETTINGS:
{
struct dvb_frontend_tune_settings* fesettings = (struct dvb_frontend_tune_settings*) arg;
@@ -1276,12 +1317,12 @@
u8 stat [] = { 0 };
u8 tda6100_buf [] = { 0, 0 };
int ret;
- struct i2c_msg msg1 [] = {{ .addr = 0x68, .buf = rpt, .len = 2 },
+ struct i2c_msg msg1 [] = {{ .addr = 0x68, .flags = 0, .buf = rpt, len: 2 },
{ .addr = 0x60, .flags = I2C_M_RD, .buf = stat, .len = 1 }};
- struct i2c_msg msg2 [] = {{ .addr = 0x68, .buf = rpt, .len = 2 },
+ struct i2c_msg msg2 [] = {{ .addr = 0x68, .flags = 0, .buf = rpt, len: 2 },
{ .addr = 0x61, .flags = I2C_M_RD, .buf = stat, .len = 1 }};
- struct i2c_msg msg3 [] = {{ .addr = 0x68, .buf = rpt, .len = 2 },
- { .addr = 0x60, .buf = tda6100_buf, .len = 2 }};
+ struct i2c_msg msg3 [] = {{ .addr = 0x68, .flags = 0, .buf = rpt, len: 2 },
+ { .addr = 0x60, .flags = 0, .buf = tda6100_buf, .len = 2 }};

stv0299_writereg (i2c, 0x01, 0x15);
stv0299_writereg (i2c, 0x02, 0x30);
diff -uraNwB linux-2.6.10-rc1/drivers/media/dvb/frontends/mt352.c linux-2.6.10-rc1-patched/drivers/media/dvb/frontends/mt352.c
--- linux-2.6.10-rc1/drivers/media/dvb/frontends/mt352.c 2004-10-25 14:07:57.000000000 +0200
+++ linux-2.6.10-rc1-patched/drivers/media/dvb/frontends/mt352.c 2004-10-25 14:14:43.000000000 +0200
@@ -8,10 +8,12 @@
* Wolfram Joost <[email protected]>
*
* Support for Samsung TDTC9251DH01C(M) tuner
- *
* Copyright (C) 2004 Antonio Mancuso <[email protected]>
* Amauri Celani <[email protected]>
*
+ * DVICO FusionHDTV DVB-T1 and DVICO FusionHDTV DVB-T Lite support by
+ * Christopher Pascoe <[email protected]>
+ *
* 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; either version 2 of the License, or
@@ -45,22 +47,23 @@
} while (0)

static int debug;
-static int force_card = -1;
-static int card_type = -1;
+#define MAX_CARDS 4
+static int force_card[MAX_CARDS] = { -1, -1, -1, -1 };
+static int force_card_count = 0;

module_param(debug, int, 0644);
MODULE_PARM_DESC(debug, "Turn on/off frontend debugging (default:off).");
-//FIXME: Should be an array.
-module_param(force_card, int, 0444);
-MODULE_PARM_DESC(force_card, "Force card type.\n\t(0 == AVDVBT771, 1 == TUA6034, "
- "2 == TDTC9251DH01C).\n\tDefault is that AVDVBT771 is attempted "
- "to be autodetected,\n\tif you do not have this card, you must "
- "specify the card type here.");
-
+module_param_array(force_card, int, &force_card_count, 0444);
+MODULE_PARM_DESC(force_card, "Forces the type of each attached mt352 frontend.\n\t"
+ "If your card is not autodetected, then you must specify its type here.\n\t"
+ "Valid card types are: 0 == AVDVBT771, 1 == TUA6034, 2 == TDTC9251DH01C,\n\t"
+ "3 == DVICO FusionHDTV DVB-T1, 4 == DVICO FusionHDTV DVB-T Lite.");

struct mt352_state {
struct i2c_adapter *i2c;
struct dvb_adapter *dvb;
+ struct dvb_frontend_info fe_info;
+ int card_type;
};

#define mt352_write(ibuf, ilen) \
@@ -75,60 +78,60 @@
} \
} while (0)

-// FIXME:
static struct _tuner_info tuner_info [] = {
- //AVERMEDIA 771 board
{
+ .fe_name = "AverMedia DVB-T 771",
.fe_frequency_min = 174000000,
.fe_frequency_max = 862000000,
- .fe_frequency_stepsize = 83333,
- .coderate_hp_shift = 7,
- .coderate_lp_shift = 4,
- .constellation_shift = 13,
- .tx_mode_shift = 0,
- .guard_interval_shift = 2,
- .hierarchy_shift = 10,
- .read_reg_flag = I2C_M_NOSTART,
+ .fe_frequency_stepsize = 166667,
+ .pll_i2c_addr = 0xc2,
.mt352_init = mt352_init_AVERMEDIA771,
.mt352_charge_pump = mt352_cp_AVERMEDIA771,
.mt352_band_select = mt352_bs_AVERMEDIA771
},
- //TUA6034 tuner
{
+ .fe_name = "Zarlink MT352 + TUA6034 DVB-T",
.fe_frequency_min = 174000000,
.fe_frequency_max = 862000000,
.fe_frequency_stepsize = 166667,
- .coderate_hp_shift = 9,
- .coderate_lp_shift = 6,
- .constellation_shift = 14,
- .tx_mode_shift = 1,
- .guard_interval_shift = 3,
- .hierarchy_shift = 12,
- .read_reg_flag = I2C_M_NOSTART,
+ .pll_i2c_addr = 0xc2,
.mt352_init = mt352_init_TUA6034,
.mt352_charge_pump = mt352_cp_TUA6034,
.mt352_band_select = mt352_bs_TUA6034
},
- //TDTC9251DH01C tuner
{
+ .fe_name = "Zarlink MT352 + Samsung TDTC9251DH01C DVB-T",
.fe_frequency_min = 474000000,
.fe_frequency_max = 858000000,
.fe_frequency_stepsize = 166667,
- .coderate_hp_shift = 9,
- .coderate_lp_shift = 6,
- .constellation_shift = 4,
- .tx_mode_shift = 1,
- .guard_interval_shift = 3,
- .hierarchy_shift = 12,
- .read_reg_flag = 0,
+ .pll_i2c_addr = 0xc2,
.mt352_init = mt352_init_TDTC9251DH01C,
.mt352_charge_pump = mt352_cp_TDTC9251DH01C,
.mt352_band_select = mt352_bs_TDTC9251DH01C
+ },
+ {
+ .fe_name = "DVICO FusionHDTV DVB-T1",
+ .fe_frequency_min = 174000000,
+ .fe_frequency_max = 862000000,
+ .fe_frequency_stepsize = 166667,
+ .pll_i2c_addr = 0xc2,
+ .mt352_init = mt352_init_DVICODVBT1,
+ .mt352_charge_pump = mt352_cp_DVICODVBT1,
+ .mt352_band_select = mt352_bs_DVICODVBT1,
+ },
+ {
+ .fe_name = "DVICO FusionHDTV DVB-T Lite",
+ .fe_frequency_min = 174000000,
+ .fe_frequency_max = 862000000,
+ .fe_frequency_stepsize = 166667,
+ .pll_i2c_addr = 0xc0,
+ .mt352_init = mt352_init_DVICODVBTLITE,
+ .mt352_charge_pump = mt352_cp_DVICODVBTLITE,
+ .mt352_band_select = mt352_bs_DVICODVBTLITE,
}
};

-
-static struct dvb_frontend_info mt352_info = {
+static struct dvb_frontend_info mt352_info_template = {
.name = "DVB-T Zarlink MT352 demodulator driver",
.type = FE_OFDM,
/*
@@ -150,63 +153,95 @@
FE_CAN_MUTE_TS
};

+static u8 mt352_reset [] = { RESET, 0x80 };
+static u8 mt352_adc_ctl_1_cfg [] = { ADC_CTL_1, 0x40 };
+static u8 mt352_capt_range_cfg[] = { CAPT_RANGE, 0x32 };
+
static int mt352_init_TUA6034(struct i2c_adapter *i2c)
{
- static u8 mt352_reset [] = { RESET, 0x80 };
static u8 mt352_clock_config [] = { CLOCK_CTL, 0x38, 0x2d };
- static u8 mt352_adc_ctl_1_cfg [] = { ADC_CTL_1, 0x40 };
static u8 mt352_agc_cfg [] = { AGC_TARGET, 0x19, 0xa0 };
- static u8 mt352_acq_ctl [] = { ACQ_CTL, 0x50 };

mt352_write(mt352_clock_config, sizeof(mt352_clock_config));
udelay(2000);
mt352_write(mt352_reset, sizeof(mt352_reset));
mt352_write(mt352_adc_ctl_1_cfg, sizeof(mt352_adc_ctl_1_cfg));
- mt352_write(mt352_acq_ctl, sizeof(mt352_acq_ctl));

mt352_write(mt352_agc_cfg, sizeof(mt352_agc_cfg));
+ mt352_write(mt352_capt_range_cfg, sizeof(mt352_capt_range_cfg));

return 0;
}

static int mt352_init_AVERMEDIA771(struct i2c_adapter *i2c)
{
- static u8 mt352_reset [] = { RESET, 0x80 };
static u8 mt352_clock_config [] = { CLOCK_CTL, 0x38, 0x2d };
- static u8 mt352_adc_ctl_1_cfg [] = { ADC_CTL_1, 0x40 };
static u8 mt352_agc_cfg [] = { AGC_TARGET, 0x10, 0x23, 0x00, 0xFF, 0xFF,
0x00, 0xFF, 0x00, 0x40, 0x40 };
- static u8 mt352_acq_ctl [] = { ACQ_CTL, 0x50 };
static u8 mt352_av771_extra[] = { 0xB5, 0x7A };
+ static u8 mt352_capt_range_cfg[] = { CAPT_RANGE, 0x32 };

mt352_write(mt352_clock_config, sizeof(mt352_clock_config));
udelay(2000);
mt352_write(mt352_reset, sizeof(mt352_reset));
mt352_write(mt352_adc_ctl_1_cfg, sizeof(mt352_adc_ctl_1_cfg));
- mt352_write(mt352_acq_ctl, sizeof(mt352_acq_ctl));

mt352_write(mt352_agc_cfg,sizeof(mt352_agc_cfg));
udelay(2000);
mt352_write(mt352_av771_extra,sizeof(mt352_av771_extra));
+ mt352_write(mt352_capt_range_cfg, sizeof(mt352_capt_range_cfg));

return 0;
}

static int mt352_init_TDTC9251DH01C(struct i2c_adapter *i2c)
{
- static u8 mt352_reset [] = { RESET, 0x80 };
static u8 mt352_clock_config [] = { CLOCK_CTL, 0x10, 0x2d };
- static u8 mt352_adc_ctl_1_cfg [] = { ADC_CTL_1, 0x40 };
static u8 mt352_agc_cfg [] = { AGC_TARGET, 0x28, 0xa1 };
- static u8 mt352_acq_ctl [] = { ACQ_CTL, 0x50 };

mt352_write(mt352_clock_config, sizeof(mt352_clock_config));
udelay(2000);
mt352_write(mt352_reset, sizeof(mt352_reset));
mt352_write(mt352_adc_ctl_1_cfg, sizeof(mt352_adc_ctl_1_cfg));
- mt352_write(mt352_acq_ctl, sizeof(mt352_acq_ctl));

mt352_write(mt352_agc_cfg, sizeof(mt352_agc_cfg));
+ mt352_write(mt352_capt_range_cfg, sizeof(mt352_capt_range_cfg));
+
+ return 0;
+}
+
+static int mt352_init_DVICODVBT1(struct i2c_adapter *i2c)
+{
+ static u8 mt352_clock_config [] = { CLOCK_CTL, 0x38, 0x39 };
+ static u8 mt352_agc_cfg [] = { AGC_TARGET, 0x24, 0x20 };
+ static u8 mt352_gpp_ctl_cfg [] = { GPP_CTL, 0x33 };
+
+ mt352_write(mt352_clock_config, sizeof(mt352_clock_config));
+ udelay(200);
+ mt352_write(mt352_reset, sizeof(mt352_reset));
+ mt352_write(mt352_adc_ctl_1_cfg, sizeof(mt352_adc_ctl_1_cfg));
+
+ mt352_write(mt352_agc_cfg, sizeof(mt352_agc_cfg));
+ mt352_write(mt352_gpp_ctl_cfg, sizeof(mt352_gpp_ctl_cfg));
+ mt352_write(mt352_capt_range_cfg, sizeof(mt352_capt_range_cfg));
+
+ return 0;
+}
+
+static int mt352_init_DVICODVBTLITE(struct i2c_adapter *i2c)
+{
+ static u8 mt352_clock_config [] = { CLOCK_CTL, 0x38, 0x38 };
+ static u8 mt352_agc_cfg [] = { AGC_TARGET, 0x28, 0x20 };
+ static u8 mt352_gpp_ctl_cfg [] = { GPP_CTL, 0x33 };
+
+ mt352_write(mt352_clock_config, sizeof(mt352_clock_config));
+ udelay(200);
+ mt352_write(mt352_reset, sizeof(mt352_reset));
+ mt352_write(mt352_adc_ctl_1_cfg, sizeof(mt352_adc_ctl_1_cfg));
+
+ mt352_write(mt352_agc_cfg, sizeof(mt352_agc_cfg));
+ mt352_write(mt352_gpp_ctl_cfg, sizeof(mt352_gpp_ctl_cfg));
+ mt352_write(mt352_capt_range_cfg, sizeof(mt352_capt_range_cfg));

return 0;
}
@@ -215,9 +250,9 @@
{
unsigned char cp = 0;

- if (freq < 542)
+ if (freq < 542000000)
cp = 0xbe;
- else if (freq < 830)
+ else if (freq < 830000000)
cp = 0xf6;
else
cp = 0xfe;
@@ -229,21 +264,21 @@
{
unsigned char cp = 0;

- if (freq < 150)
+ if (freq < 150000000)
cp = 0xB4;
- else if (freq < 173)
+ else if (freq < 173000000)
cp = 0xBC;
- else if (freq < 250)
+ else if (freq < 250000000)
cp = 0xB4;
- else if (freq < 400)
+ else if (freq < 400000000)
cp = 0xBC;
- else if (freq < 420)
+ else if (freq < 420000000)
cp = 0xF4;
- else if (freq < 470)
+ else if (freq < 470000000)
cp = 0xFC;
- else if (freq < 600)
+ else if (freq < 600000000)
cp = 0xBC;
- else if (freq < 730)
+ else if (freq < 730000000)
cp = 0xF4;
else
cp = 0xFC;
@@ -256,11 +291,39 @@
return(0xcc);
}

+static unsigned char mt352_cp_DVICODVBT1(u32 freq)
+{
+ unsigned char cp = 0;
+
+ if (freq < 542000000)
+ cp = 0xbc;
+ else if (freq < 830000000)
+ cp = 0xf4;
+ else
+ cp = 0xfc;
+
+ return cp;
+}
+
+static unsigned char mt352_cp_DVICODVBTLITE(u32 freq)
+{
+ unsigned char cp = 0;
+
+ if (freq < 542000000)
+ cp = 0xb4;
+ else if (freq < 771000000)
+ cp = 0xbc;
+ else
+ cp = 0xf4;
+
+ return cp;
+}
+
static unsigned char mt352_bs_TUA6034(u32 freq)
{
unsigned char bs = 0;

- if (freq < 250)
+ if (freq < 250000000)
bs = 0x01;
else
bs = 0x08;
@@ -272,21 +335,21 @@
{
unsigned char bs = 0;

- if (freq < 150)
+ if (freq < 150000000)
bs = 0x01;
- else if (freq < 173)
+ else if (freq < 173000000)
bs = 0x01;
- else if (freq < 250)
+ else if (freq < 250000000)
bs = 0x02;
- else if (freq < 400)
+ else if (freq < 400000000)
bs = 0x02;
- else if (freq < 420)
+ else if (freq < 420000000)
bs = 0x02;
- else if (freq < 470)
+ else if (freq < 470000000)
bs = 0x02;
- else if (freq < 600)
+ else if (freq < 600000000)
bs = 0x08;
- else if (freq < 730)
+ else if (freq < 730000000)
bs = 0x08;
else
bs = 0x08;
@@ -298,54 +361,79 @@
{
unsigned char bs = 0;

- if ((freq >= 48) && (freq <= 154)) /* low band */
+ if (freq >= 48000000 && freq <= 154000000) /* low band */
bs = 0x09;

- if ((freq >= 161) && (freq <= 439)) /* medium band */
+ if (freq >= 161000000 && freq <= 439000000) /* medium band */
bs = 0x0a;

- if ((freq >= 447) && (freq <= 863)) /* high band */
+ if (freq >= 447000000 && freq <= 863000000) /* high band */
bs = 0x08;

return bs;
}

+static unsigned char mt352_bs_DVICODVBT1(u32 freq)
+{
+ unsigned char bs = 0;
+
+ if (freq == 0) /* power down PLL */
+ bs = 0x03;
+ else if (freq < 157500000) /* low band */
+ bs = 0x01;
+ else if (freq < 443250000) /* mid band */
+ bs = 0x02;
+ else /* high band */
+ bs = 0x04;

-static int mt352_detect_avermedia_771(struct i2c_adapter *i2c)
+ return bs;
+}
+
+static unsigned char mt352_bs_DVICODVBTLITE(u32 freq)
{
- int i;
- u8 reg;
- u8 id[4];
- const u8 pciid[4] = { 0x07, 0x71, 0x14, 0x61 };
- struct i2c_msg msg[2] =
+ unsigned char bs = 0;
+
+ if (freq == 0) /* power down PLL */
+ bs = 0x03;
+ else if (freq < 443250000) /* mid band */
+ bs = 0x02;
+ else /* high band */
+ bs = 0x08;
+
+ return bs;
+}
+
+static u32 mt352_read_eeprom_dword(struct i2c_adapter *i2c, int dword_base)
{
+ int i;
+ u32 dword = 0;
+ u8 reg, val;
+ struct i2c_msg msg[2] = {
{
.addr = 0x50,
- .flags = I2C_M_NOSTART,
+ .flags = 0,
.buf = &reg,
.len = 1
},
{
.addr = 0x50,
.flags = I2C_M_RD,
+ .buf = &val,
.len = 1
}
};

- for (i = 0; i < 4; i++)
- {
- reg = i + 0xFC;
- msg[1].buf = id + i;
+ for (i = 0; i < 4; i++) {
+ reg = dword_base + i;
if (i2c_transfer(i2c,msg,2) != 2)
- {
return 0;
- }
+ dword = (dword << 8) | val;
}

- return *((u32 *) id) == *((u32 *) pciid);
+ return dword;
}

-static int mt352_init(struct i2c_adapter *i2c)
+static int mt352_init(struct i2c_adapter *i2c, int card_type)
{
/**
* all register write sequence have the register address of the
@@ -366,7 +454,7 @@

static int mt352_sleep(struct i2c_adapter *i2c)
{
- static u8 mt352_softdown[] = { 0x89, 0x20, 0x08 };
+ static u8 mt352_softdown[] = { CLOCK_CTL, 0x20, 0x08 };

mt352_write(mt352_softdown, sizeof(mt352_softdown));

@@ -374,26 +462,27 @@
}

static int mt352_set_parameters(struct i2c_adapter *i2c,
- struct dvb_frontend_parameters *param)
+ struct dvb_frontend_parameters *param,
+ int card_type)
{
unsigned char buf[14];
unsigned int tps = 0;
struct dvb_ofdm_parameters *op = &param->u.ofdm;
- u32 freq = param->frequency / 1000000;
uint16_t tmp;
+ int i;

switch (op->code_rate_HP) {
case FEC_2_3:
- tps |= (1 << CODERATE_HP_SHIFT);
+ tps |= (1 << 7);
break;
case FEC_3_4:
- tps |= (2 << CODERATE_HP_SHIFT);
+ tps |= (2 << 7);
break;
case FEC_5_6:
- tps |= (3 << CODERATE_HP_SHIFT);
+ tps |= (3 << 7);
break;
case FEC_7_8:
- tps |= (4 << CODERATE_HP_SHIFT);
+ tps |= (4 << 7);
break;
case FEC_1_2:
case FEC_AUTO:
@@ -404,20 +493,24 @@

switch (op->code_rate_LP) {
case FEC_2_3:
- tps |= (1 << CODERATE_LP_SHIFT);
+ tps |= (1 << 4);
break;
case FEC_3_4:
- tps |= (2 << CODERATE_LP_SHIFT);
+ tps |= (2 << 4);
break;
case FEC_5_6:
- tps |= (3 << CODERATE_LP_SHIFT);
+ tps |= (3 << 4);
break;
case FEC_7_8:
- tps |= (4 << CODERATE_LP_SHIFT);
+ tps |= (4 << 4);
break;
case FEC_1_2:
case FEC_AUTO:
break;
+ case FEC_NONE:
+ if (op->hierarchy_information == HIERARCHY_AUTO ||
+ op->hierarchy_information == HIERARCHY_NONE)
+ break;
default:
return -EINVAL;
}
@@ -427,10 +520,10 @@
break;
case QAM_AUTO:
case QAM_16:
- tps |= (1 << CONSTELLATION_SHIFT);
+ tps |= (1 << 13);
break;
case QAM_64:
- tps |= (2 << CONSTELLATION_SHIFT);
+ tps |= (2 << 13);
break;
default:
return -EINVAL;
@@ -441,7 +534,7 @@
case TRANSMISSION_MODE_AUTO:
break;
case TRANSMISSION_MODE_8K:
- tps |= (1 << TX_MODE_SHIFT);
+ tps |= (1 << 0);
break;
default:
return -EINVAL;
@@ -452,13 +545,13 @@
case GUARD_INTERVAL_AUTO:
break;
case GUARD_INTERVAL_1_16:
- tps |= (1 << GUARD_INTERVAL_SHIFT);
+ tps |= (1 << 2);
break;
case GUARD_INTERVAL_1_8:
- tps |= (2 << GUARD_INTERVAL_SHIFT);
+ tps |= (2 << 2);
break;
case GUARD_INTERVAL_1_4:
- tps |= (3 << GUARD_INTERVAL_SHIFT);
+ tps |= (3 << 2);
break;
default:
return -EINVAL;
@@ -469,13 +562,13 @@
case HIERARCHY_NONE:
break;
case HIERARCHY_1:
- tps |= (1 << HIERARCHY_SHIFT);
+ tps |= (1 << 10);
break;
case HIERARCHY_2:
- tps |= (2 << HIERARCHY_SHIFT);
+ tps |= (2 << 10);
break;
case HIERARCHY_4:
- tps |= (3 << HIERARCHY_SHIFT);
+ tps |= (3 << 10);
break;
default:
return -EINVAL;
@@ -507,7 +600,7 @@
buf[6] = 0x31; /* INPUT_FREQ_(1|0), 20.48MHz clock, 36.166667MHz IF */
buf[7] = 0x05; /* see MT352 Design Manual page 32 for details */

- buf[8] = I2C_TUNER_ADDR;
+ buf[8] = PLL_I2C_ADDR;

/**
* All the following settings are tuner module dependent,
@@ -516,17 +609,24 @@

/* here we assume 1/6MHz == 166.66kHz stepsize */
#define IF_FREQUENCYx6 217 /* 6 * 36.16666666667MHz */
- tmp = ((param->frequency*3)/500000) + IF_FREQUENCYx6;
+ tmp = (((param->frequency + 83333) * 3) / 500000) + IF_FREQUENCYx6;

buf[9] = msb(tmp); /* CHAN_START_(1|0) */
buf[10] = lsb(tmp);

- buf[11] = MT352_CHARGE_PUMP(freq);
- buf[12] = MT352_BAND_SELECT(freq);
+ buf[11] = MT352_CHARGE_PUMP(param->frequency);
+ buf[12] = MT352_BAND_SELECT(param->frequency);

buf[13] = 0x01; /* TUNER_GO!! */

+ /* Only send the tuning request if the tuner doesn't have the requested
+ * parameters already set. Enhances tuning time and prevents stream
+ * breakup when retuning the same transponder. */
+ for (i = 1; i < 13; i++)
+ if (buf[i] != mt352_read_register(i2c, i + 0x50)) {
mt352_write(buf, sizeof(buf));
+ break;
+ }

return 0;
}
@@ -537,7 +637,7 @@
u8 b0 [] = { reg };
u8 b1 [] = { 0 };
struct i2c_msg msg [] = { { .addr = I2C_MT352_ADDR,
- .flags = READ_REG_FLAG,
+ .flags = 0,
.buf = b0, .len = 1 },
{ .addr = I2C_MT352_ADDR,
.flags = I2C_M_RD,
@@ -672,6 +772,7 @@
{
struct mt352_state *state = fe->data;
struct i2c_adapter *i2c = state->i2c;
+ int card_type = state->card_type;
u8 r,snr;
fe_status_t *status;
u16 signal;
@@ -679,7 +780,7 @@

switch (cmd) {
case FE_GET_INFO:
- memcpy (arg, &mt352_info, sizeof(struct dvb_frontend_info));
+ memcpy(arg, &state->fe_info, sizeof(struct dvb_frontend_info));
break;

case FE_READ_STATUS:
@@ -727,7 +828,8 @@

case FE_SET_FRONTEND:
return mt352_set_parameters (i2c,
- (struct dvb_frontend_parameters *) arg);
+ (struct dvb_frontend_parameters *) arg,
+ card_type);

case FE_GET_FRONTEND:
return mt352_get_parameters (i2c,
@@ -744,7 +846,13 @@
return mt352_sleep(i2c);

case FE_INIT:
- return mt352_init(i2c);
+ /* Only send the initialisation command if the demodulator
+ * isn't already enabled. Greatly enhances tuning time. */
+ if ((mt352_read_register(i2c, CLOCK_CTL) & 0x10) == 0 ||
+ (mt352_read_register(i2c, CONFIG) & 0x20) == 0)
+ return mt352_init(i2c, card_type);
+ else
+ return 0;

default:
return -EOPNOTSUPP;
@@ -757,56 +865,83 @@

static int mt352_attach_adapter(struct i2c_adapter *i2c)
{
+ static int num_cards_probed;
struct mt352_state *state;
struct i2c_client *client;
- static u8 mt352_reset_attach [] = { 0x50, 0xC0 };
+ static u8 mt352_reset_attach [] = { RESET, 0xC0 };
int ret;
+ int card_type, forced_card = -1;

dprintk("Trying to attach to adapter 0x%x:%s.\n",
i2c->id, i2c->name);

- /* set the proper MT352 frequency range */
- mt352_info.frequency_min = FE_FREQ_MIN;
- mt352_info.frequency_max = FE_FREQ_MAX;
- mt352_info.frequency_stepsize = FE_FREQ_STEPSIZE;
+ if (mt352_read_register(i2c, CHIP_ID) != ID_MT352)
+ return -ENODEV;

if ( !(state = kmalloc(sizeof(struct mt352_state), GFP_KERNEL)) )
return -ENOMEM;

memset(state, 0, sizeof(struct mt352_state));
state->i2c = i2c;
+ state->card_type = -1;
+ memcpy(&state->fe_info, &mt352_info_template, sizeof(struct dvb_frontend_info));

- if (mt352_detect_avermedia_771(i2c)) {
- card_type = CARD_AVDVBT771;
- } else if (force_card < 0) {
- dprintk("Avermedia 771 not detected, maybe you should try the "
- "'force_card' module parameter?.\n");
- kfree(state);
- return -ENODEV;
+ /* Attempt autodetection of card type based on PCI ID information
+ * stored in any on-board EEPROM. */
+ switch (mt352_read_eeprom_dword(i2c, 0xFC)) { /* BT878A chipset */
+ case 0x07711461:
+ state->card_type = CARD_AVDVBT771;
+ break;
+ case 0xdb1018ac:
+ state->card_type = CARD_DVICODVBTLITE;
+ break;
+ default:
+ break;
}

- if (force_card > 0) {
- if (card_type >= 0 && force_card != card_type)
- printk(KERN_WARNING "dvbfe_mt352: Warning, overriding"
- " detected card.\n");
- card_type = force_card;
+ switch (mt352_read_eeprom_dword(i2c, 0x04)) { /* CX2388x chipset */
+ case 0xac1800db:
+ state->card_type = CARD_DVICODVBT1;
+ break;
+ default:
+ break;
}

- if (mt352_read_register(i2c, CHIP_ID) != ID_MT352) {
+ if (num_cards_probed < force_card_count)
+ forced_card = force_card[num_cards_probed++];
+
+ if (state->card_type == -1 && forced_card < 0) {
+ dprintk("Card type not automatically detected. You "
+ "must use the 'force_card' module parameter.\n");
kfree(state);
return -ENODEV;
}

- if (card_type == CARD_AVDVBT771)
- printk(KERN_INFO FRONTEND_NAME ": Setup for Avermedia 771.\n");
- else if (card_type == CARD_TUA6034)
- printk(KERN_INFO FRONTEND_NAME ": Setup for TUA6034.\n");
- else if (card_type == CARD_TDTC9251DH01C)
- printk(KERN_INFO FRONTEND_NAME ": Setup for TDTC9251DH01C.\n");
+ if (forced_card >= 0) {
+ if (state->card_type >= 0 && forced_card != state->card_type)
+ printk(KERN_WARNING FRONTEND_NAME ": Warning, overriding"
+ " detected card type.\n");
+ state->card_type = forced_card;
+ }
+
+ card_type = state->card_type;
+ printk(KERN_INFO FRONTEND_NAME ": Setup for %s\n", FE_NAME);
+
+ /* set the frontend name and card-specific frequency info */
+ strlcpy(state->fe_info.name, FE_NAME, sizeof(state->fe_info.name));
+ state->fe_info.frequency_min = FE_FREQ_MIN;
+ state->fe_info.frequency_max = FE_FREQ_MAX;
+ state->fe_info.frequency_stepsize = FE_FREQ_STEPSIZE;

/* Do a "hard" reset */
mt352_write(mt352_reset_attach, sizeof(mt352_reset_attach));

+ /* Try to intiialise the device */
+ if (mt352_init(i2c, card_type) != 0) {
+ kfree(state);
+ return -ENODEV;
+ }
+
if ( !(client = kmalloc(sizeof(struct i2c_client), GFP_KERNEL)) ) {
kfree(state);
return -ENOMEM;
@@ -823,16 +958,6 @@
return ret;
}

- BUG_ON(!state->dvb);
-
- if ((ret = dvb_register_frontend(mt352_ioctl, state->dvb, state,
- &mt352_info, THIS_MODULE))) {
- i2c_detach_client(client);
- kfree(client);
- kfree(state);
- return ret;
- }
-
return 0;
}

@@ -840,9 +965,9 @@
{
struct mt352_state *state = i2c_get_clientdata(client);

+ if (state->dvb)
dvb_unregister_frontend (mt352_ioctl, state->dvb);
i2c_detach_client(client);
- BUG_ON(state->dvb);
kfree(client);
kfree(state);
return 0;
@@ -851,13 +976,23 @@
static int mt352_command (struct i2c_client *client, unsigned int cmd, void *arg)
{
struct mt352_state *state = i2c_get_clientdata(client);
+ int ret;

switch (cmd) {
case FE_REGISTER:
+ if (!state->dvb) {
+ if ((ret = dvb_register_frontend(mt352_ioctl, arg,
+ state, &state->fe_info,
+ THIS_MODULE)))
+ return ret;
state->dvb = arg;
+ }
break;
case FE_UNREGISTER:
+ if (state->dvb == arg) {
+ dvb_unregister_frontend(mt352_ioctl, state->dvb);
state->dvb = NULL;
+ }
break;
default:
return -EOPNOTSUPP;
diff -uraNwB linux-2.6.10-rc1/drivers/media/dvb/frontends/mt352.h linux-2.6.10-rc1-patched/drivers/media/dvb/frontends/mt352.h
--- linux-2.6.10-rc1/drivers/media/dvb/frontends/mt352.h 2004-10-25 14:07:57.000000000 +0200
+++ linux-2.6.10-rc1-patched/drivers/media/dvb/frontends/mt352.h 2004-10-25 14:14:43.000000000 +0200
@@ -4,11 +4,16 @@
* Written by Holger Waechtler <[email protected]>
* and Daniel Mack <[email protected]>
*
- * Support for Samsung TDTC9251DH01C(M) tuner
+ * AVerMedia AVerTV DVB-T 771 support by
+ * Wolfram Joost <[email protected]>
*
+ * Support for Samsung TDTC9251DH01C(M) tuner
* Copyright (C) 2004 Antonio Mancuso <[email protected]>
* Amauri Celani <[email protected]>
*
+ * DVICO FusionHDTV DVB-T1 and DVICO FusionHDTV DVB-T Lite support by
+ * Christopher Pascoe <[email protected]>
+ *
* 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; either version 2 of the License, or
@@ -29,12 +34,13 @@
#define _MT352_

#define I2C_MT352_ADDR 0x0f
-#define I2C_TUNER_ADDR 0xc2
#define ID_MT352 0x13

#define CARD_AVDVBT771 0x00
#define CARD_TUA6034 0x01
#define CARD_TDTC9251DH01C 0x02
+#define CARD_DVICODVBT1 0x03
+#define CARD_DVICODVBTLITE 0x04

#define msb(x) (((x) >> 8) & 0xff)
#define lsb(x) ((x) & 0xff)
@@ -123,6 +129,9 @@
};

struct _tuner_info {
+ char *fe_name;
+#define FE_NAME tuner_info[card_type].fe_name
+
__u32 fe_frequency_min;
#define FE_FREQ_MIN tuner_info[card_type].fe_frequency_min

@@ -132,26 +141,8 @@
__u32 fe_frequency_stepsize; //verificare se u32 e' corretto
#define FE_FREQ_STEPSIZE tuner_info[card_type].fe_frequency_stepsize

- __u32 coderate_hp_shift; //verificare se u32 giusto
-#define CODERATE_HP_SHIFT tuner_info[card_type].coderate_hp_shift
-
- __u32 coderate_lp_shift;
-#define CODERATE_LP_SHIFT tuner_info[card_type].coderate_lp_shift
-
- int constellation_shift;
-#define CONSTELLATION_SHIFT tuner_info[card_type].constellation_shift
-
- int tx_mode_shift;
-#define TX_MODE_SHIFT tuner_info[card_type].tx_mode_shift
-
- int guard_interval_shift;
-#define GUARD_INTERVAL_SHIFT tuner_info[card_type].guard_interval_shift
-
- int hierarchy_shift;
-#define HIERARCHY_SHIFT tuner_info[card_type].hierarchy_shift
-
- int read_reg_flag;
-#define READ_REG_FLAG tuner_info[card_type].read_reg_flag
+ u8 pll_i2c_addr;
+#define PLL_I2C_ADDR tuner_info[card_type].pll_i2c_addr

int (* mt352_init) (struct i2c_adapter *i2c);
#define MT352_INIT tuner_info[card_type].mt352_init
@@ -166,12 +157,18 @@
static int mt352_init_TUA6034(struct i2c_adapter *i2c);
static int mt352_init_AVERMEDIA771(struct i2c_adapter *i2c);
static int mt352_init_TDTC9251DH01C(struct i2c_adapter *i2c);
+static int mt352_init_DVICODVBT1(struct i2c_adapter *i2c);
+static int mt352_init_DVICODVBTLITE(struct i2c_adapter *i2c);
static unsigned char mt352_cp_TUA6034(u32 freq);
static unsigned char mt352_cp_AVERMEDIA771(u32 freq);
static unsigned char mt352_cp_TDTC9251DH01C(u32 freq);
+static unsigned char mt352_cp_DVICODVBT1(u32 freq);
+static unsigned char mt352_cp_DVICODVBTLITE(u32 freq);
static unsigned char mt352_bs_TUA6034(u32 freq);
static unsigned char mt352_bs_AVERMEDIA771(u32 freq);
static unsigned char mt352_bs_TDTC9251DH01C(u32 freq);
-static int mt352_detect_avermedia_771(struct i2c_adapter *i2c);
+static unsigned char mt352_bs_DVICODVBT1(u32 freq);
+static unsigned char mt352_bs_DVICODVBTLITE(u32 freq);
+static u8 mt352_read_register(struct i2c_adapter *i2c, u8 reg);

#endif /* _MT352_ */


Attachments:
05-dvb-frontend-update.diff (28.95 kB)