[media] dvb: modify core to implement interfaces/entities at MC new gen
authorMauro Carvalho Chehab <mchehab@osg.samsung.com>
Fri, 21 Aug 2015 19:18:18 +0000 (16:18 -0300)
committerMauro Carvalho Chehab <mchehab@osg.samsung.com>
Mon, 11 Jan 2016 14:18:52 +0000 (12:18 -0200)
The Media Controller New Generation redefines the types for both
interfaces and entities to be used on DVB. Make the needed
changes at the DVB core for all interfaces, entities and
data and interface links to appear in the graph.

Acked-by: Hans Verkuil <hans.verkuil@cisco.com>
Signed-off-by: Mauro Carvalho Chehab <mchehab@osg.samsung.com>
13 files changed:
drivers/media/dvb-core/dmxdev.c
drivers/media/dvb-core/dvb_ca_en50221.c
drivers/media/dvb-core/dvb_frontend.c
drivers/media/dvb-core/dvb_net.c
drivers/media/dvb-core/dvbdev.c
drivers/media/dvb-core/dvbdev.h
drivers/media/firewire/firedtv-ci.c
drivers/media/pci/bt8xx/dst_ca.c
drivers/media/pci/ddbridge/ddbridge-core.c
drivers/media/pci/ngene/ngene-core.c
drivers/media/pci/ttpci/av7110.c
drivers/media/pci/ttpci/av7110_av.c
drivers/media/pci/ttpci/av7110_ca.c

index ea9abde902e9eb4b34075f970f905e9021f96a09..a168cbe1c9985804f4e2547c39917f3c7c137994 100644 (file)
@@ -1244,9 +1244,9 @@ int dvb_dmxdev_init(struct dmxdev *dmxdev, struct dvb_adapter *dvb_adapter)
        }
 
        dvb_register_device(dvb_adapter, &dmxdev->dvbdev, &dvbdev_demux, dmxdev,
-                           DVB_DEVICE_DEMUX);
+                           DVB_DEVICE_DEMUX, dmxdev->filternum);
        dvb_register_device(dvb_adapter, &dmxdev->dvr_dvbdev, &dvbdev_dvr,
-                           dmxdev, DVB_DEVICE_DVR);
+                           dmxdev, DVB_DEVICE_DVR, dmxdev->filternum);
 
        dvb_ringbuffer_init(&dmxdev->dvr_buffer, NULL, 8192);
 
index fb66184dc9b665f38ac73f952b1b32af46c875ab..f82cd1ff4f3a015481ef1125cb8f096aaf761132 100644 (file)
@@ -1695,7 +1695,7 @@ int dvb_ca_en50221_init(struct dvb_adapter *dvb_adapter,
        pubca->private = ca;
 
        /* register the DVB device */
-       ret = dvb_register_device(dvb_adapter, &ca->dvbdev, &dvbdev_ca, ca, DVB_DEVICE_CA);
+       ret = dvb_register_device(dvb_adapter, &ca->dvbdev, &dvbdev_ca, ca, DVB_DEVICE_CA, 0);
        if (ret)
                goto free_slot_info;
 
index 42ab6aaeed7d1187d5da4ad7010fc6e115ca08a5..40080645341e727a6380feac3f991fb022b86bf4 100644 (file)
@@ -2759,7 +2759,7 @@ int dvb_register_frontend(struct dvb_adapter* dvb,
                        fe->dvb->num, fe->id, fe->ops.info.name);
 
        dvb_register_device (fe->dvb, &fepriv->dvbdev, &dvbdev_template,
-                            fe, DVB_DEVICE_FRONTEND);
+                            fe, DVB_DEVICE_FRONTEND, 0);
 
        /*
         * Initialize the cache to the proper values according with the
index ce4332e80a910fe653632ad4a9b870eb675bd592..ce6a711b42d4926fa41dbd7ddbc749250c45755c 100644 (file)
@@ -1502,6 +1502,6 @@ int dvb_net_init (struct dvb_adapter *adap, struct dvb_net *dvbnet,
                dvbnet->state[i] = 0;
 
        return dvb_register_device(adap, &dvbnet->dvbdev, &dvbdev_net,
-                            dvbnet, DVB_DEVICE_NET);
+                            dvbnet, DVB_DEVICE_NET, 0);
 }
 EXPORT_SYMBOL(dvb_net_init);
index dadcf165507054dcc43ccfe8dcaf9213a08879e6..6babc688801bbe82de55c9968690a4d8c1eb8c96 100644 (file)
@@ -180,18 +180,86 @@ skip:
        return -ENFILE;
 }
 
+static void dvb_create_tsout_entity(struct dvb_device *dvbdev,
+                                   const char *name, int npads)
+{
+#if defined(CONFIG_MEDIA_CONTROLLER_DVB)
+       int i, ret = 0;
+
+       dvbdev->tsout_pads = kcalloc(npads, sizeof(*dvbdev->tsout_pads),
+                                    GFP_KERNEL);
+       if (!dvbdev->tsout_pads)
+               return;
+       dvbdev->tsout_entity = kcalloc(npads, sizeof(*dvbdev->tsout_entity),
+                                      GFP_KERNEL);
+       if (!dvbdev->tsout_entity) {
+               kfree(dvbdev->tsout_pads);
+               dvbdev->tsout_pads = NULL;
+               return;
+       }
+       for (i = 0; i < npads; i++) {
+               struct media_pad *pads = &dvbdev->tsout_pads[i];
+               struct media_entity *entity = &dvbdev->tsout_entity[i];
+
+               entity->name = kasprintf(GFP_KERNEL, "%s #%d", name, i);
+               if (!entity->name) {
+                       ret = -ENOMEM;
+                       break;
+               }
+
+               entity->type = MEDIA_ENT_T_DVB_TSOUT;
+               pads->flags = MEDIA_PAD_FL_SINK;
+
+               ret = media_entity_init(entity, 1, pads);
+               if (ret < 0)
+                       break;
+
+               ret = media_device_register_entity(dvbdev->adapter->mdev,
+                                                  entity);
+               if (ret < 0)
+                       break;
+       }
+
+       if (!ret) {
+               dvbdev->tsout_num_entities = npads;
+               return;
+       }
+
+       for (i--; i >= 0; i--) {
+               media_device_unregister_entity(&dvbdev->tsout_entity[i]);
+               kfree(dvbdev->tsout_entity[i].name);
+       }
+
+       printk(KERN_ERR
+               "%s: media_device_register_entity failed for %s\n",
+               __func__, name);
+
+       kfree(dvbdev->tsout_entity);
+       kfree(dvbdev->tsout_pads);
+       dvbdev->tsout_entity = NULL;
+       dvbdev->tsout_pads = NULL;
+#endif
+}
+
+#define DEMUX_TSOUT    "demux-tsout"
+#define DVR_TSOUT      "dvr-tsout"
+
 static void dvb_create_media_entity(struct dvb_device *dvbdev,
-                                      int type, int minor)
+                                   int type, int demux_sink_pads)
 {
 #if defined(CONFIG_MEDIA_CONTROLLER_DVB)
-       int ret = 0, npads;
+       int i, ret = 0, npads;
 
        switch (type) {
        case DVB_DEVICE_FRONTEND:
                npads = 2;
                break;
+       case DVB_DEVICE_DVR:
+               dvb_create_tsout_entity(dvbdev, DVR_TSOUT, demux_sink_pads);
+               return;
        case DVB_DEVICE_DEMUX:
-               npads = 2;
+               npads = 1 + demux_sink_pads;
+               dvb_create_tsout_entity(dvbdev, DEMUX_TSOUT, demux_sink_pads);
                break;
        case DVB_DEVICE_CA:
                npads = 2;
@@ -215,8 +283,6 @@ static void dvb_create_media_entity(struct dvb_device *dvbdev,
        if (!dvbdev->entity)
                return;
 
-       dvbdev->entity->info.dev.major = DVB_MAJOR;
-       dvbdev->entity->info.dev.minor = minor;
        dvbdev->entity->name = dvbdev->name;
 
        if (npads) {
@@ -237,7 +303,8 @@ static void dvb_create_media_entity(struct dvb_device *dvbdev,
        case DVB_DEVICE_DEMUX:
                dvbdev->entity->type = MEDIA_ENT_T_DVB_DEMUX;
                dvbdev->pads[0].flags = MEDIA_PAD_FL_SINK;
-               dvbdev->pads[1].flags = MEDIA_PAD_FL_SOURCE;
+               for (i = 1; i < npads; i++)
+                       dvbdev->pads[i].flags = MEDIA_PAD_FL_SOURCE;
                break;
        case DVB_DEVICE_CA:
                dvbdev->entity->type = MEDIA_ENT_T_DVB_CA;
@@ -259,8 +326,16 @@ static void dvb_create_media_entity(struct dvb_device *dvbdev,
                printk(KERN_ERR
                        "%s: media_device_register_entity failed for %s\n",
                        __func__, dvbdev->entity->name);
+
+               media_device_unregister_entity(dvbdev->entity);
+               for (i = 0; i < dvbdev->tsout_num_entities; i++) {
+                       media_device_unregister_entity(&dvbdev->tsout_entity[i]);
+                       kfree(dvbdev->tsout_entity[i].name);
+               }
                kfree(dvbdev->pads);
                kfree(dvbdev->entity);
+               kfree(dvbdev->tsout_pads);
+               kfree(dvbdev->tsout_entity);
                dvbdev->entity = NULL;
                return;
        }
@@ -271,7 +346,8 @@ static void dvb_create_media_entity(struct dvb_device *dvbdev,
 }
 
 static void dvb_register_media_device(struct dvb_device *dvbdev,
-                                     int type, int minor)
+                                     int type, int minor,
+                                     unsigned demux_sink_pads)
 {
 #if defined(CONFIG_MEDIA_CONTROLLER_DVB)
        u32 intf_type;
@@ -279,7 +355,7 @@ static void dvb_register_media_device(struct dvb_device *dvbdev,
        if (!dvbdev->adapter->mdev)
                return;
 
-       dvb_create_media_entity(dvbdev, type, minor);
+       dvb_create_media_entity(dvbdev, type, demux_sink_pads);
 
        switch (type) {
        case DVB_DEVICE_FRONTEND:
@@ -323,7 +399,8 @@ static void dvb_register_media_device(struct dvb_device *dvbdev,
 }
 
 int dvb_register_device(struct dvb_adapter *adap, struct dvb_device **pdvbdev,
-                       const struct dvb_device *template, void *priv, int type)
+                       const struct dvb_device *template, void *priv, int type,
+                       int demux_sink_pads)
 {
        struct dvb_device *dvbdev;
        struct file_operations *dvbdevfops;
@@ -402,7 +479,7 @@ int dvb_register_device(struct dvb_adapter *adap, struct dvb_device **pdvbdev,
        dprintk(KERN_DEBUG "DVB: register adapter%d/%s%d @ minor: %i (0x%02x)\n",
                adap->num, dnames[type], id, minor, minor);
 
-       dvb_register_media_device(dvbdev, type, minor);
+       dvb_register_media_device(dvbdev, type, minor, demux_sink_pads);
 
        return 0;
 }
@@ -422,9 +499,18 @@ void dvb_unregister_device(struct dvb_device *dvbdev)
 
 #if defined(CONFIG_MEDIA_CONTROLLER_DVB)
        if (dvbdev->entity) {
+               int i;
+
                media_device_unregister_entity(dvbdev->entity);
+               for (i = 0; i < dvbdev->tsout_num_entities; i++) {
+                       media_device_unregister_entity(&dvbdev->tsout_entity[i]);
+                       kfree(dvbdev->tsout_entity[i].name);
+               }
+
                kfree(dvbdev->entity);
                kfree(dvbdev->pads);
+               kfree(dvbdev->tsout_entity);
+               kfree(dvbdev->tsout_pads);
        }
 #endif
 
@@ -440,8 +526,10 @@ void dvb_create_media_graph(struct dvb_adapter *adap)
 {
        struct media_device *mdev = adap->mdev;
        struct media_entity *entity, *tuner = NULL, *demod = NULL;
-       struct media_entity *demux = NULL, *dvr = NULL, *ca = NULL;
+       struct media_entity *demux = NULL, *ca = NULL;
        struct media_interface *intf;
+       unsigned demux_pad = 0;
+       unsigned dvr_pad = 0;
 
        if (!mdev)
                return;
@@ -457,9 +545,6 @@ void dvb_create_media_graph(struct dvb_adapter *adap)
                case MEDIA_ENT_T_DVB_DEMUX:
                        demux = entity;
                        break;
-               case MEDIA_ENT_T_DVB_TSOUT:
-                       dvr = entity;
-                       break;
                case MEDIA_ENT_T_DVB_CA:
                        ca = entity;
                        break;
@@ -471,21 +556,46 @@ void dvb_create_media_graph(struct dvb_adapter *adap)
 
        if (demod && demux)
                media_create_pad_link(demod, 1, demux, 0, MEDIA_LNK_FL_ENABLED);
-
-       if (demux && dvr)
-               media_create_pad_link(demux, 1, dvr, 0, MEDIA_LNK_FL_ENABLED);
-
        if (demux && ca)
                media_create_pad_link(demux, 1, ca, 0, MEDIA_LNK_FL_ENABLED);
 
+       /* Create demux links for each ringbuffer/pad */
+       if (demux) {
+               media_device_for_each_entity(entity, mdev) {
+                       if (entity->type == MEDIA_ENT_T_DVB_TSOUT) {
+                               if (!strncmp(entity->name, DVR_TSOUT,
+                                       strlen(DVR_TSOUT)))
+                                       media_create_pad_link(demux,
+                                                             ++dvr_pad,
+                                                       entity, 0, 0);
+                               if (!strncmp(entity->name, DEMUX_TSOUT,
+                                       strlen(DEMUX_TSOUT)))
+                                       media_create_pad_link(demux,
+                                                             ++demux_pad,
+                                                       entity, 0, 0);
+                       }
+               }
+       }
+
        /* Create indirect interface links for FE->tuner, DVR->demux and CA->ca */
        list_for_each_entry(intf, &mdev->interfaces, list) {
                if (intf->type == MEDIA_INTF_T_DVB_CA && ca)
                        media_create_intf_link(ca, intf, 0);
                if (intf->type == MEDIA_INTF_T_DVB_FE && tuner)
                        media_create_intf_link(tuner, intf, 0);
+
                if (intf->type == MEDIA_INTF_T_DVB_DVR && demux)
                        media_create_intf_link(demux, intf, 0);
+
+               media_device_for_each_entity(entity, mdev) {
+                       if (entity->type == MEDIA_ENT_T_DVB_TSOUT) {
+                               if (!strcmp(entity->name, DVR_TSOUT))
+                                       media_create_intf_link(entity, intf, 0);
+                               if (!strcmp(entity->name, DEMUX_TSOUT))
+                                       media_create_intf_link(entity, intf, 0);
+                               break;
+                       }
+               }
        }
 }
 EXPORT_SYMBOL_GPL(dvb_create_media_graph);
index 8398c8fb02b0330458112b8a51ec75eb923fadc0..7af8adbb589b885982ae40de12bc83e9b5ca10d0 100644 (file)
@@ -148,9 +148,11 @@ struct dvb_device {
        const char *name;
 
        /* Allocated and filled inside dvbdev.c */
-       struct media_entity *entity;
        struct media_intf_devnode *intf_devnode;
-       struct media_pad *pads;
+
+       unsigned tsout_num_entities;
+       struct media_entity *entity, *tsout_entity;
+       struct media_pad *pads, *tsout_pads;
 #endif
 
        void *priv;
@@ -193,7 +195,8 @@ int dvb_register_device(struct dvb_adapter *adap,
                        struct dvb_device **pdvbdev,
                        const struct dvb_device *template,
                        void *priv,
-                       int type);
+                       int type,
+                       int demux_sink_pads);
 
 /**
  * dvb_unregister_device - Unregisters a DVB device
index e63f582378bfff5193078f5bcdc6fe15713b8247..edbb30fdd9d95e3d5285c892bce0111b0f315598 100644 (file)
@@ -241,7 +241,7 @@ int fdtv_ca_register(struct firedtv *fdtv)
                return -EFAULT;
 
        err = dvb_register_device(&fdtv->adapter, &fdtv->cadev,
-                                 &fdtv_ca, fdtv, DVB_DEVICE_CA);
+                                 &fdtv_ca, fdtv, DVB_DEVICE_CA, 0);
 
        if (stat.ca_application_info == 0)
                dev_err(fdtv->device, "CaApplicationInfo is not set\n");
index c5cc14ef8347cbca567085237ab4ee6ed06038b9..da8b414fd824ca5541ab1f298d42f954576ab311 100644 (file)
@@ -705,7 +705,8 @@ struct dvb_device *dst_ca_attach(struct dst_state *dst, struct dvb_adapter *dvb_
        struct dvb_device *dvbdev;
 
        dprintk(verbose, DST_CA_ERROR, 1, "registering DST-CA device");
-       if (dvb_register_device(dvb_adapter, &dvbdev, &dvbdev_ca, dst, DVB_DEVICE_CA) == 0) {
+       if (dvb_register_device(dvb_adapter, &dvbdev, &dvbdev_ca, dst,
+                               DVB_DEVICE_CA, 0) == 0) {
                dst->dst_ca = dvbdev;
                return dst->dst_ca;
        }
index fba5b40a869c50a705d74f5831436f139d08c27e..9d5b314142f1b49daabb78985f6d13a2f982405a 100644 (file)
@@ -1065,7 +1065,7 @@ static int ddb_ci_attach(struct ddb_port *port)
                            port->en, 0, 1);
        ret = dvb_register_device(&port->output->adap, &port->output->dev,
                                  &dvbdev_ci, (void *) port->output,
-                                 DVB_DEVICE_SEC);
+                                 DVB_DEVICE_SEC, 0);
        return ret;
 }
 
index 1b92d836a564fd364862acab2e761602e62744bd..4e924e2d1638fe2d98d034f90e0263070dab1982 100644 (file)
@@ -1513,7 +1513,7 @@ static int init_channel(struct ngene_channel *chan)
                set_transfer(&chan->dev->channel[2], 1);
                dvb_register_device(adapter, &chan->ci_dev,
                                    &ngene_dvbdev_ci, (void *) chan,
-                                   DVB_DEVICE_SEC);
+                                   DVB_DEVICE_SEC, 0);
                if (!chan->ci_dev)
                        goto err;
        }
index 5e18b6796ed949b2db1b1bf9ce07a70ba3a8de71..a69dc6a0752bb94fc8352c133571b31f37599f99 100644 (file)
@@ -1358,7 +1358,7 @@ static int av7110_register(struct av7110 *av7110)
 
 #ifdef CONFIG_DVB_AV7110_OSD
        dvb_register_device(&av7110->dvb_adapter, &av7110->osd_dev,
-                           &dvbdev_osd, av7110, DVB_DEVICE_OSD);
+                           &dvbdev_osd, av7110, DVB_DEVICE_OSD, 0);
 #endif
 
        dvb_net_init(&av7110->dvb_adapter, &av7110->dvb_net, &dvbdemux->dmx);
index 6fc748e2201736b4da5c8b11859f60712c874e1c..26c5696c193bf244aa098e6c99e205dc4475710b 100644 (file)
@@ -1594,10 +1594,10 @@ int av7110_av_register(struct av7110 *av7110)
        memset(&av7110->video_size, 0, sizeof (video_size_t));
 
        dvb_register_device(&av7110->dvb_adapter, &av7110->video_dev,
-                           &dvbdev_video, av7110, DVB_DEVICE_VIDEO);
+                           &dvbdev_video, av7110, DVB_DEVICE_VIDEO, 0);
 
        dvb_register_device(&av7110->dvb_adapter, &av7110->audio_dev,
-                           &dvbdev_audio, av7110, DVB_DEVICE_AUDIO);
+                           &dvbdev_audio, av7110, DVB_DEVICE_AUDIO, 0);
 
        return 0;
 }
index bc4c65ffd4b9872ed25895300d9dc716a52bee2c..96a130fb4595729b880aab0aba9ab4ab75faddb8 100644 (file)
@@ -378,7 +378,7 @@ static struct dvb_device dvbdev_ca = {
 int av7110_ca_register(struct av7110 *av7110)
 {
        return dvb_register_device(&av7110->dvb_adapter, &av7110->ca_dev,
-                                  &dvbdev_ca, av7110, DVB_DEVICE_CA);
+                                  &dvbdev_ca, av7110, DVB_DEVICE_CA, 0);
 }
 
 void av7110_ca_unregister(struct av7110 *av7110)