R: [linux-dvb] How to handle multiple frontends?

Eddi eddi at depieri.net
Mon Jan 15 09:42:39 CET 2007


Hi Ralph, you said...

>Or should just the demuxes lock against each other? So, if one 
>demux has filters set, the other one will not accept any.
>I guess the frontends themselve work at the same time, they 
>just share the same TS input?

>We'll definitely need some better input handling for those new cards.
>E.g. if you have 2 demuxes connected to 2 frontends or data from the
>PC, 1 or 2 decoders on the card, one or more of those new USB CAMs serving
>one of several cards, etc. 
>I'm starting to do some hacking with something like modified V4 API +
>multi-proto frontends + other goodies ...

Please look at Steve Toth HVR3000 repository at
http://linuxtv.org/hg/~stoth/hvr3000
and my patch to his repository for FlyDVB trio at
http://tux.dpeddi.com/lr319sta/downloads/multi_fe_trio_final.patch

That repository already enable multiple frontend on cx88 hardware, while my
patch use his multiple frontend enabled core with saa7134 hardware.

Both card use have an architecture where different tuner/demux are attached
to a shared bus.

The repository and my patch enable on card with multiple frontend both
frontend by creating frontend0,frontend1. Both driver if  trying to open the
other frontend, make the open by application to exit with error (return
-EBUSY;).

I don't know if this is the best solution, but give it an eye if you don't
already done!

Frontend switching routine in both driver:
Steve Toth:
cx88/cx88-mpeg.c
/* Driver asked for hardware access. */
int cx8802_request_acquire(struct cx8802_driver *drv)
{
	struct cx88_core *core = drv->core;

	/* Fail a request for hardware if the device is busy. */
	if (core->active_type_id != CX88_BOARD_NONE)
		return -EBUSY;
	if (drv->advise_acquire)
	{
		core->active_type_id = drv->type_id;
		drv->advise_acquire(drv);

		mpeg_dbg(1,"%s() Post acquire GPIO=%x\n", __FUNCTION__,
cx_read(MO_GP0_IO));
	}
	return 0;
}

My patch:
+static int saa7134_dvb_bus_ctrl(struct dvb_frontend* fe,
+	int acquire)
+{
+	struct saa7134_dev *dev = fe->dvb->priv;
+	int ret = 0;
+	int fe_id;
+
+	dprintk(1, "%s(acquire=%d)\n", __FUNCTION__, acquire);
+
+	fe_id = videobuf_dvb_find_frontend(&dev->felist, fe);
+	if (!fe_id) {
+		printk(KERN_ERR "%s() No frontend found\n", __FUNCTION__);
+		return -EINVAL;
+	}
+
+	if(acquire) {
+		if (dev->felist.active_fe_id != 0)
+			return -EBUSY;
+		else
+			dev->felist.active_fe_id = fe_id;
+
+		if (dev->felist.active_fe_id == 1) {
+    			/* try to reset the hardware (SWRST) */
+    			saa_writeb(SAA7134_SPECIAL_MODE, 0x00);
+			msleep(10);
+			saa_writeb(SAA7134_SPECIAL_MODE, 0x01);
+			udelay(1000);
+		}
+		if (dev->felist.active_fe_id == 2) {
+    			/* try to reset the hardware (SWRST) */
+    			saa_writeb(SAA7134_SPECIAL_MODE, 0x00);
+			msleep(10);
+			saa_writeb(SAA7134_SPECIAL_MODE, 0x01);
+			udelay(1000);
+		}
+	} else {
+		dev->felist.active_fe_id = 0;
+	}
+
+	dprintk(1, "%s(acquire=%d) returns %d\n", __FUNCTION__, acquire,
ret);
+	return ret;
+}

Thanks to Klaus for his try to enable multiple frontend on his VDR
application!

Best regards,
Eddi De Pieri








More information about the linux-dvb mailing list