diff options
author | Mauro Carvalho Chehab <mchehab@redhat.com> | 2009-01-06 16:06:07 -0300 |
---|---|---|
committer | Mauro Carvalho Chehab <mchehab@redhat.com> | 2009-01-07 22:18:56 -0200 |
commit | e32fadc4c2e5975a8e40541e2ba72a7032ed4cf4 (patch) | |
tree | 7718a6d3d28f6e70d8c51e8ef0eef72022935c19 /drivers/media/video/cx88/cx88-dvb.c | |
parent | 571d864c68d429a82fd61e97404a2de210ffc72d (diff) |
V4L/DVB (10190): cx88: Fix some Kbuild troubles
As Randy Dunlap <randy.dunlap@oracle.com> reported, cx88 has some compilation issues:
drivers/built-in.o: In function `cx88_call_i2c_clients':
(.text+0x20af17): undefined reference to `videobuf_dvb_get_frontend'
drivers/built-in.o: In function `cx8802_probe':
cx88-mpeg.c:(.devinit.text+0x268c4): undefined reference to `videobuf_dvb_alloc_frontend'
cx88-mpeg.c:(.devinit.text+0x268ea): undefined reference to `videobuf_dvb_dealloc_frontends'
With those configs:
CONFIG_VIDEO_CX88=y
CONFIG_VIDEO_CX88_BLACKBIRD=y
CONFIG_VIDEO_CX88_DVB=m
CONFIG_DVB_CORE=m
After carefully examining the code, with the current code, several cx88 drivers
(cx8800, cx8802, cx88_dvb and cx88_blackbird) should be compiled as a module,
if one of them is marked as such. Just fixing Kconfig could create a very complex
set of rules. Also, this hides a problem with the current approach where the dvb
functionality weren't confined inside dvb module.
What happens is that:
- cx88-i2c (part of cx8800) has some special rules if DVB;
- cx88-mpeg (cx8802 module) has also part of DVB init code;
- cx88-dvb has the rest of the dvb code;
- cx88-blackbird can be used with cx88-mpeg, having cx88-dvb or not.
So, instead of doing some tricks at Kconfig and wait for a next breakage,
this patch moves the dvb code inside cx88-i2c and cx88-mpeg into cx88-dvb.
Another problem is that cx8802 were being compiled, even without cx88-dvb
and cx88-blackbird modules.
While on this code, let's fix also a reported problem:
http://www.linuxtv.org/pipermail/linux-dvb/2009-January/031225.html
A solution for the issue were proposed here:
http://www.mail-archive.com/linux-media@vger.kernel.org/msg00021.html
Thanks to Randy, Andy, Gregoire and Thomas for helping us to detect
and solve the issues.
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
Diffstat (limited to 'drivers/media/video/cx88/cx88-dvb.c')
-rw-r--r-- | drivers/media/video/cx88/cx88-dvb.c | 46 |
1 files changed, 46 insertions, 0 deletions
diff --git a/drivers/media/video/cx88/cx88-dvb.c b/drivers/media/video/cx88/cx88-dvb.c index da4dd4913d9f..613dfea4ff3e 100644 --- a/drivers/media/video/cx88/cx88-dvb.c +++ b/drivers/media/video/cx88/cx88-dvb.c @@ -138,6 +138,28 @@ static int cx88_dvb_bus_ctrl(struct dvb_frontend* fe, int acquire) return ret; } +static void cx88_dvb_gate_ctrl(struct cx88_core *core, int open) +{ + struct videobuf_dvb_frontends *f; + struct videobuf_dvb_frontend *fe; + + if (!core->dvbdev) + return; + + f = &core->dvbdev->frontends; + + if (!f) + return; + + if (f->gate <= 1) /* undefined or fe0 */ + fe = videobuf_dvb_get_frontend(f, 1); + else + fe = videobuf_dvb_get_frontend(f, f->gate); + + if (fe && fe->dvb.frontend && fe->dvb.frontend->ops.i2c_gate_ctrl) + fe->dvb.frontend->ops.i2c_gate_ctrl(fe->dvb.frontend, open); +} + /* ------------------------------------------------------------------ */ static int dvico_fusionhdtv_demod_init(struct dvb_frontend* fe) @@ -597,12 +619,30 @@ static int dvb_register(struct cx8802_dev *dev) struct cx88_core *core = dev->core; struct videobuf_dvb_frontend *fe0, *fe1 = NULL; int mfe_shared = 0; /* bus not shared by default */ + int i; if (0 != core->i2c_rc) { printk(KERN_ERR "%s/2: no i2c-bus available, cannot attach dvb drivers\n", core->name); goto frontend_detach; } + if (!core->board.num_frontends) + return -EINVAL; + + mutex_init(&dev->frontends.lock); + INIT_LIST_HEAD(&dev->frontends.felist); + + printk(KERN_INFO "%s() allocating %d frontend(s)\n", __func__, + core->board.num_frontends); + for (i = 1; i <= core->board.num_frontends; i++) { + fe0 = videobuf_dvb_alloc_frontend(&dev->frontends, i); + if (!fe0) { + printk(KERN_ERR "%s() failed to alloc\n", __func__); + videobuf_dvb_dealloc_frontends(&dev->frontends); + goto frontend_detach; + } + } + /* Get the first frontend */ fe0 = videobuf_dvb_get_frontend(&dev->frontends, 1); if (!fe0) @@ -611,6 +651,9 @@ static int dvb_register(struct cx8802_dev *dev) /* multi-frontend gate control is undefined or defaults to fe0 */ dev->frontends.gate = 0; + /* Sets the gate control callback to be used by i2c command calls */ + core->gate_ctrl = cx88_dvb_gate_ctrl; + /* init frontend(s) */ switch (core->boardnr) { case CX88_BOARD_HAUPPAUGE_DVB_T1: @@ -1109,6 +1152,7 @@ static int dvb_register(struct cx8802_dev *dev) &dev->pci->dev, adapter_nr, mfe_shared); frontend_detach: + core->gate_ctrl = NULL; videobuf_dvb_dealloc_frontends(&dev->frontends); return -EINVAL; } @@ -1270,6 +1314,8 @@ static int cx8802_dvb_remove(struct cx8802_driver *drv) vp3054_i2c_remove(dev); + core->gate_ctrl = NULL; + return 0; } |