[linux-dvb] Multiple demods on a single transport bus

Steven Toth stoth at hauppauge.com
Fri Sep 15 04:52:03 CEST 2006


Hi,

I'm working on drivers for three products that share a single transport 
bus with two or more demodulators or other pieces of silicon.

A good example of this is the hvr1300. 
http://www.linuxtv.org/hg/~stoth/hvr1300.

Other examples are the HVR3000 (which has a cx22702 and cx24123 sharing) 
and HVR4000 products which has a cx22702 and cx24118 sharing.

With the hvr1300 device, the transport bus is shared between a MPEG2 
hardware encoder and a cx22702. Rather than add specific code to the 
cx22702 demodulator to use a series of callbacks back into the cx88 
framework, to toggle GPIOs and request hardware access, it started to 
make more sense to add this as part of the generic frontend framework 
and not pollute the demodulator drivers.

The following patch to dvb-frontend.c|h uses a callback during open and 
release in dvb_frontend to determine whether the request should succeed.

I'm also showing you a typical implementation within the cx88 framework. 
We override the fe->ops function with a generic framework callback in 
the cx88 source to deal with the specifics for this device. (much of the 
hardware arbitration is not shown here but can be seen in 
hg/~stoth/hvr1300 for those who are interested).

A minor patch like this to dvb-frontend.c|h would allow dvb frameworks 
(cx88/budget etc) to determine whether hardware was technically free for 
use, or make it available if required.

Is this type of changing likely to cause any unforeseen problems?

Does anyone object to this approach?

Regards,

Steve


diff -r 3e90edbf7c53 linux/drivers/media/dvb/dvb-core/dvb_frontend.c
--- a/linux/drivers/media/dvb/dvb-core/dvb_frontend.c    Thu Sep 14 
18:41:13 2006
+++ b/linux/drivers/media/dvb/dvb-core/dvb_frontend.c    Thu Sep 14 
22:30:06 2006
@@ -1020,6 +1020,13 @@
     if ((ret = dvb_generic_open (inode, file)) < 0)
         return ret;
 
+    if (fe->ops.ts_bus_ctrl) {
+        if ((ret = fe->ops.ts_bus_ctrl (fe, 1)) < 0) {
+            dvb_generic_release (inode, file);
+            return ret;
+        }
+    }
+
     if ((file->f_flags & O_ACCMODE) != O_RDONLY) {
 
         /* normal tune mode when opened R/W */
@@ -1048,6 +1055,9 @@
 
     if ((file->f_flags & O_ACCMODE) != O_RDONLY)
         fepriv->release_jiffies = jiffies;
+
+    if (fe->ops.ts_bus_ctrl)
+        fe->ops.ts_bus_ctrl (fe, 0);
 
     return dvb_generic_release (inode, file);
 }
diff -r 3e90edbf7c53 linux/drivers/media/dvb/dvb-core/dvb_frontend.h
--- a/linux/drivers/media/dvb/dvb-core/dvb_frontend.h    Thu Sep 14 
18:41:13 2006
+++ b/linux/drivers/media/dvb/dvb-core/dvb_frontend.h    Thu Sep 14 
22:30:06 2006
@@ -129,6 +129,7 @@
     int (*enable_high_lnb_voltage)(struct dvb_frontend* fe, long arg);
     int (*dishnetwork_send_legacy_command)(struct dvb_frontend* fe, 
unsigned long cmd);
     int (*i2c_gate_ctrl)(struct dvb_frontend* fe, int enable);
+    int (*ts_bus_ctrl)(struct dvb_frontend* fe, int acquire);
 
     struct dvb_tuner_ops tuner_ops;
 };
diff -r 3e90edbf7c53 linux/drivers/media/video/cx88/cx88-dvb.c
--- a/linux/drivers/media/video/cx88/cx88-dvb.c    Thu Sep 14 18:41:13 2006
+++ b/linux/drivers/media/video/cx88/cx88-dvb.c    Thu Sep 14 22:30:06 2006
@@ -506,6 +506,29 @@
     .lnb_polarity  = 1,
 };
 
+static int cx88_dvb_bus_ctrl(struct dvb_frontend *fe, int acquire)
+{
+    struct cx8802_dev *dev= fe->dvb->priv;
+    struct cx8802_driver *drv = NULL;
+    int ret = 0;
+
+    dprintk(1, "%s(acquire=%d)\n", __FUNCTION__, acquire);
+
+    switch (dev->core->board) {
+    case CX88_BOARD_HAUPPAUGE_HVR1300:
+        drv = cx8802_get_driver(dev, CX88_BOARD_DVB);
+        if (drv) {
+            if(acquire)
+                ret = drv->request_acquire(drv);
+            else
+                ret = drv->request_release(drv);
+        }
+        break;
+    }
+
+    return ret;
+}
+
 static int dvb_register(struct cx8802_dev *dev)
 {
     /* init struct videobuf_dvb */
@@ -557,6 +580,8 @@
             dvb_attach(dvb_pll_attach, dev->dvb.frontend, 0x61,
                    &dev->core->i2c_adap,
                    &dvb_pll_fmd1216me);
+
+            dev->dvb.frontend->ops.ts_bus_ctrl = cx88_dvb_bus_ctrl;
         }
         break;
     case CX88_BOARD_DVICO_FUSIONHDTV_DVB_T_PLUS:







More information about the linux-dvb mailing list