Skip to contentSkip to conversation

S2API: add multifrontend

PATCH New Hans Werner 1 participant 1 message Sep 11, 2008 Media (V4L/DVB)

lore
Share & tools
lore
#0 lore raw

PATCH 2/2 S2API: add multifrontend

Second and last part of the patch.

Regards,
Hans

Signature · 2 lines
GMX Kostenlose Spiele: Einfach online spielen und Spaß haben mit Pastry Passion!
http://games.entertainment.gmx.net/de/entertainment/games/free/puzzle/6169196
linux/drivers/media/video/cx88/cx88-i2c.c +35 -5
diff -r ffa9a0c644b3 linux/drivers/media/video/cx88/cx88-i2c.c
@@ -116,18 +116,23 @@ static int detach_inform(struct i2c_clie
 
 void cx88_call_i2c_clients(struct cx88_core *core, unsigned int cmd, void *arg)
 {
+	struct videobuf_dvb_frontend *fe0 = NULL;
 	if (0 != core->i2c_rc)
 		return;
 
 #if defined(CONFIG_VIDEO_CX88_DVB) || defined(CONFIG_VIDEO_CX88_DVB_MODULE)
-	if ( (core->dvbdev) && (core->dvbdev->dvb.frontend) ) {
-		if (core->dvbdev->dvb.frontend->ops.i2c_gate_ctrl)
-			core->dvbdev->dvb.frontend->ops.i2c_gate_ctrl(core->dvbdev->dvb.frontend, 1);
+	if (core->dvbdev) {
+		/* Get the first frontend and assume that all I2C is routed through it */
+		/* TODO: Get _THIS_FE_ then find the right i2c_gate_ctrl for it */
+		fe0 = videobuf_dvb_get_frontend(&core->dvbdev->frontends, 1);
+
+		if (fe0 && fe0->dvb.frontend && fe0->dvb.frontend->ops.i2c_gate_ctrl)
+			fe0->dvb.frontend->ops.i2c_gate_ctrl(fe0->dvb.frontend, 1);
 
 		i2c_clients_command(&core->i2c_adap, cmd, arg);
 
-		if (core->dvbdev->dvb.frontend->ops.i2c_gate_ctrl)
-			core->dvbdev->dvb.frontend->ops.i2c_gate_ctrl(core->dvbdev->dvb.frontend, 0);
+		if (fe0 && fe0->dvb.frontend && fe0->dvb.frontend->ops.i2c_gate_ctrl)
+			fe0->dvb.frontend->ops.i2c_gate_ctrl(fe0->dvb.frontend, 0);
 	} else
 #endif
 		i2c_clients_command(&core->i2c_adap, cmd, arg);
@@ -201,7 +206,32 @@ int cx88_i2c_init(struct cx88_core *core
 
 	core->i2c_rc = i2c_bit_add_bus(&core->i2c_adap);
 	if (0 == core->i2c_rc) {
+	        static u8 tuner_data[] =
+			{ 0x0b, 0xdc, 0x86, 0x52 };
+		static struct i2c_msg tuner_msg =
+			{ .flags = 0, .addr = 0xc2 >> 1, .buf = tuner_data, .len = 4 };
+
 		dprintk(1, "i2c register ok\n");
+
+		switch( core->boardnr )
+		{
+		    case CX88_BOARD_HAUPPAUGE_HVR1300:
+		    case CX88_BOARD_HAUPPAUGE_HVR3000: /* ? */
+		    case CX88_BOARD_HAUPPAUGE_HVR4000:
+			/*
+  	 		 * The tda9887 2-0043: tda988[5/6/7] found @ 0x43 (tuner')
+ 	 		 * is disabled after a cold boot on the HVR devices.
+  	 		 *
+  	 		 * We enable it here prior to probing for successful detection.
+  	 		 *
+  	 		 * This has been tested on the HVR1300 and HVR4000. (dmb).
+  	 		 */
+			printk("%s: i2c init: enabling analog demod on HVR1300/3000/4000 tuner\n",
+				core->name);
+			i2c_transfer(core->i2c_client.adapter, &tuner_msg, 1);
+			break;
+		}
+
 		if (i2c_scan)
 			do_i2c_scan(core->name,&core->i2c_client);
 	} else
linux/drivers/media/video/cx88/cx88-input.c +1 -0
diff -r ffa9a0c644b3 linux/drivers/media/video/cx88/cx88-input.c
@@ -485,6 +485,7 @@ void cx88_ir_irq(struct cx88_core *core)
 	case CX88_BOARD_HAUPPAUGE_HVR4000LITE:
 		ircode = ir_decode_biphase(ir->samples, ir->scount, 5, 7);
 		ir_dprintk("biphase decoded: %x\n", ircode);
+//TODO Darron has other code here
 		if ((ircode & 0xfffff000) != 0x3000)
 			break;
 		ir_input_keydown(ir->input, &ir->ir, ircode & 0x3f, ircode);
linux/drivers/media/video/cx88/cx88-mpeg.c +21 -1
diff -r ffa9a0c644b3 linux/drivers/media/video/cx88/cx88-mpeg.c
@@ -808,7 +808,8 @@ static int __devinit cx8802_probe(struct
 {
 	struct cx8802_dev *dev;
 	struct cx88_core  *core;
-	int err;
+	struct videobuf_dvb_frontend *demod;
+	int err,i;
 
 	/* general setup */
 	core = cx88_core_get(pci_dev);
@@ -820,6 +821,11 @@ static int __devinit cx8802_probe(struct
 	err = -ENODEV;
 	if (!core->board.mpeg)
 		goto fail_core;
+
+	if (!core->board.num_frontends) {
+		printk(KERN_ERR "%s() .num_frontends should be non-zero, err = %d\n", __FUNCTION__, err);
+		goto fail_core;
+	}
 
 	err = -ENOMEM;
 	dev = kzalloc(sizeof(*dev),GFP_KERNEL);
@@ -834,6 +840,20 @@ static int __devinit cx8802_probe(struct
 
 	INIT_LIST_HEAD(&dev->drvlist);
 	list_add_tail(&dev->devlist,&cx8802_devlist);
+
+	mutex_init(&dev->frontends.lock);
+	INIT_LIST_HEAD(&dev->frontends.frontend.felist);
+
+	printk(KERN_INFO "%s() allocating %d frontend(s)\n", __FUNCTION__, core->board.num_frontends);
+
+	for (i = 1; i <= core->board.num_frontends; i++) {
+		demod = videobuf_dvb_alloc_frontend(dev, &dev->frontends, i);
+		if(demod == NULL) {
+			printk(KERN_ERR "%s() failed to alloc\n", __FUNCTION__);
+			err = -ENOMEM;
+			goto fail_free;
+		}
+	}
 
 	/* Maintain a reference so cx88-video can query the 8802 device. */
 	core->dvbdev = dev;
linux/drivers/media/video/cx88/cx88.h +3 -1
diff -r ffa9a0c644b3 linux/drivers/media/video/cx88/cx88.h
@@ -257,6 +257,7 @@ struct cx88_board {
 	struct cx88_input       radio;
 	enum cx88_board_type    mpeg;
 	unsigned int            audio_chip;
+	int			num_frontends;
 };
 
 struct cx88_subid {
@@ -354,6 +355,7 @@ struct cx88_core {
 	struct cx8802_dev          *dvbdev;
 	enum cx88_board_type       active_type_id;
 	int			   active_ref;
+	int			   active_fe_id;
 };
 
 struct cx8800_dev;
@@ -505,7 +507,7 @@ struct cx8802_dev {
 
 #if defined(CONFIG_VIDEO_CX88_DVB) || defined(CONFIG_VIDEO_CX88_DVB_MODULE)
 	/* for dvb only */
-	struct videobuf_dvb        dvb;
+	struct videobuf_dvb_frontends frontends;
 #endif
 
 #if defined(CONFIG_VIDEO_CX88_VP3054) || \
linux/drivers/media/video/saa7134/saa7134-dvb.c +105 -89

410 lines not on this page · raw message

linux/drivers/media/video/saa7134/saa7134.h +1 -1
diff -r ffa9a0c644b3 linux/drivers/media/video/saa7134/saa7134.h
@@ -580,7 +580,7 @@ struct saa7134_dev {
 
 #if defined(CONFIG_VIDEO_SAA7134_DVB) || defined(CONFIG_VIDEO_SAA7134_DVB_MODULE)
 	/* SAA7134_MPEG_DVB only */
-	struct videobuf_dvb        dvb;
+	struct videobuf_dvb_frontends frontends;
 	int (*original_demod_sleep)(struct dvb_frontend *fe);
 	int (*original_set_voltage)(struct dvb_frontend *fe, fe_sec_voltage_t voltage);
 	int (*original_set_high_voltage)(struct dvb_frontend *fe, long arg);
linux/drivers/media/video/videobuf-dvb.c +149 -24

216 lines not on this page · raw message

linux/include/media/videobuf-dvb.h +33 -3
diff -r ffa9a0c644b3 linux/include/media/videobuf-dvb.h
@@ -24,12 +24,42 @@ struct videobuf_dvb {
 	struct dvb_net             net;
 };
 
-int videobuf_dvb_register(struct videobuf_dvb *dvb,
+struct videobuf_dvb_frontend {
+	void *dev;
+	struct list_head felist;
+	int id;
+	struct videobuf_dvb dvb;
+};
+
+struct videobuf_dvb_frontends {
+	struct mutex lock;
+	struct dvb_adapter adapter;
+	int active_fe_id; /* Indicates which frontend in the felist is in use */
+	struct videobuf_dvb_frontend frontend;
+};
+
+int videobuf_dvb_register_bus(struct videobuf_dvb_frontends *f,
 			  struct module *module,
 			  void *adapter_priv,
 			  struct device *device,
-			  short *adapter_nr);
-void videobuf_dvb_unregister(struct videobuf_dvb *dvb);
+			  short *adapter_nr);   //NEW
+
+void videobuf_dvb_unregister_bus(struct videobuf_dvb_frontends *f);
+
+int videobuf_dvb_register_adapter(struct videobuf_dvb_frontends *f,
+			  struct module *module,
+			  void *adapter_priv,
+			  struct device *device,
+			  char *adapter_name,
+			  short *adapter_nr);   //NEW
+
+int videobuf_dvb_register_frontend(struct dvb_adapter *adapter, struct videobuf_dvb *dvb);
+
+struct videobuf_dvb_frontend * videobuf_dvb_alloc_frontend(void *private, struct videobuf_dvb_frontends *f, int id);
+
+struct videobuf_dvb_frontend * videobuf_dvb_get_frontend(struct videobuf_dvb_frontends *f, int id);
+int videobuf_dvb_find_frontend(struct videobuf_dvb_frontends *f, struct dvb_frontend *p);
+
 
 /*
  * Local variables:

_______________________________________________
linux-dvb mailing list
[email protected]
http://www.linuxtv.org/cgi-bin/mailman/listinfo/linux-dvb