]> git.karo-electronics.de Git - karo-tx-linux.git/blobdiff - drivers/media/dvb-core/dvbdev.c
Merge branch 'fix/bcm2835-code' of git://git.kernel.org/pub/scm/linux/kernel/git...
[karo-tx-linux.git] / drivers / media / dvb-core / dvbdev.c
index f98fd3b29afefbdadede9e0d6ff104fb28135e12..13bb57f0457f7f9514628c177ae00784bc4e4461 100644 (file)
@@ -184,7 +184,7 @@ static void dvb_register_media_device(struct dvb_device *dvbdev,
                                      int type, int minor)
 {
 #if defined(CONFIG_MEDIA_CONTROLLER_DVB)
-       int ret;
+       int ret = 0, npads;
 
        if (!dvbdev->adapter->mdev)
                return;
@@ -196,18 +196,48 @@ static void dvb_register_media_device(struct dvb_device *dvbdev,
        dvbdev->entity->info.dev.major = DVB_MAJOR;
        dvbdev->entity->info.dev.minor = minor;
        dvbdev->entity->name = dvbdev->name;
+
+       switch (type) {
+       case DVB_DEVICE_CA:
+       case DVB_DEVICE_DEMUX:
+       case DVB_DEVICE_FRONTEND:
+               npads = 2;
+               break;
+       case DVB_DEVICE_NET:
+               npads = 0;
+               break;
+       default:
+               npads = 1;
+       }
+
+       if (npads) {
+               dvbdev->pads = kcalloc(npads, sizeof(*dvbdev->pads),
+                                      GFP_KERNEL);
+               if (!dvbdev->pads) {
+                       kfree(dvbdev->entity);
+                       return;
+               }
+       }
+
        switch (type) {
        case DVB_DEVICE_FRONTEND:
                dvbdev->entity->type = MEDIA_ENT_T_DEVNODE_DVB_FE;
+               dvbdev->pads[0].flags = MEDIA_PAD_FL_SINK;
+               dvbdev->pads[1].flags = MEDIA_PAD_FL_SOURCE;
                break;
        case DVB_DEVICE_DEMUX:
                dvbdev->entity->type = MEDIA_ENT_T_DEVNODE_DVB_DEMUX;
+               dvbdev->pads[0].flags = MEDIA_PAD_FL_SINK;
+               dvbdev->pads[1].flags = MEDIA_PAD_FL_SOURCE;
                break;
        case DVB_DEVICE_DVR:
                dvbdev->entity->type = MEDIA_ENT_T_DEVNODE_DVB_DVR;
+               dvbdev->pads[0].flags = MEDIA_PAD_FL_SINK;
                break;
        case DVB_DEVICE_CA:
                dvbdev->entity->type = MEDIA_ENT_T_DEVNODE_DVB_CA;
+               dvbdev->pads[0].flags = MEDIA_PAD_FL_SINK;
+               dvbdev->pads[1].flags = MEDIA_PAD_FL_SOURCE;
                break;
        case DVB_DEVICE_NET:
                dvbdev->entity->type = MEDIA_ENT_T_DEVNODE_DVB_NET;
@@ -218,12 +248,16 @@ static void dvb_register_media_device(struct dvb_device *dvbdev,
                return;
        }
 
-       ret = media_device_register_entity(dvbdev->adapter->mdev,
-                                          dvbdev->entity);
+       if (npads)
+               ret = media_entity_init(dvbdev->entity, npads, dvbdev->pads, 0);
+       if (!ret)
+               ret = media_device_register_entity(dvbdev->adapter->mdev,
+                                                  dvbdev->entity);
        if (ret < 0) {
                printk(KERN_ERR
                        "%s: media_device_register_entity failed for %s\n",
                        __func__, dvbdev->entity->name);
+               kfree(dvbdev->pads);
                kfree(dvbdev->entity);
                dvbdev->entity = NULL;
                return;
@@ -336,6 +370,7 @@ void dvb_unregister_device(struct dvb_device *dvbdev)
        if (dvbdev->entity) {
                media_device_unregister_entity(dvbdev->entity);
                kfree(dvbdev->entity);
+               kfree(dvbdev->pads);
        }
 #endif
 
@@ -345,6 +380,52 @@ void dvb_unregister_device(struct dvb_device *dvbdev)
 }
 EXPORT_SYMBOL(dvb_unregister_device);
 
+
+#ifdef CONFIG_MEDIA_CONTROLLER_DVB
+void dvb_create_media_graph(struct dvb_adapter *adap)
+{
+       struct media_device *mdev = adap->mdev;
+       struct media_entity *entity, *tuner = NULL, *fe = NULL;
+       struct media_entity *demux = NULL, *dvr = NULL, *ca = NULL;
+
+       if (!mdev)
+               return;
+
+       media_device_for_each_entity(entity, mdev) {
+               switch (entity->type) {
+               case MEDIA_ENT_T_V4L2_SUBDEV_TUNER:
+                       tuner = entity;
+                       break;
+               case MEDIA_ENT_T_DEVNODE_DVB_FE:
+                       fe = entity;
+                       break;
+               case MEDIA_ENT_T_DEVNODE_DVB_DEMUX:
+                       demux = entity;
+                       break;
+               case MEDIA_ENT_T_DEVNODE_DVB_DVR:
+                       dvr = entity;
+                       break;
+               case MEDIA_ENT_T_DEVNODE_DVB_CA:
+                       ca = entity;
+                       break;
+               }
+       }
+
+       if (tuner && fe)
+               media_entity_create_link(tuner, 0, fe, 0, 0);
+
+       if (fe && demux)
+               media_entity_create_link(fe, 1, demux, 0, MEDIA_LNK_FL_ENABLED);
+
+       if (demux && dvr)
+               media_entity_create_link(demux, 1, dvr, 0, MEDIA_LNK_FL_ENABLED);
+
+       if (demux && ca)
+               media_entity_create_link(demux, 1, ca, 0, MEDIA_LNK_FL_ENABLED);
+}
+EXPORT_SYMBOL_GPL(dvb_create_media_graph);
+#endif
+
 static int dvbdev_check_free_adapter_num(int num)
 {
        struct list_head *entry;