]> git.karo-electronics.de Git - karo-tx-linux.git/blobdiff - drivers/media/usb/cx231xx/cx231xx-cards.c
[media] media-device: move PCI/USB helper functions from v4l2-mc
[karo-tx-linux.git] / drivers / media / usb / cx231xx / cx231xx-cards.c
index 89dc695c696e5b154b6543f2b85c83459b13a622..29bd7536feedab2da17f66a132db2ab3e1ad6cb2 100644 (file)
@@ -1172,6 +1172,7 @@ static void cx231xx_unregister_media_device(struct cx231xx *dev)
 #ifdef CONFIG_MEDIA_CONTROLLER
        if (dev->media_dev) {
                media_device_unregister(dev->media_dev);
+               media_device_cleanup(dev->media_dev);
                kfree(dev->media_dev);
                dev->media_dev = NULL;
        }
@@ -1185,8 +1186,6 @@ static void cx231xx_unregister_media_device(struct cx231xx *dev)
 */
 void cx231xx_release_resources(struct cx231xx *dev)
 {
-       cx231xx_unregister_media_device(dev);
-
        cx231xx_release_analog_resources(dev);
 
        cx231xx_remove_from_devlist(dev);
@@ -1199,78 +1198,27 @@ void cx231xx_release_resources(struct cx231xx *dev)
        /* delete v4l2 device */
        v4l2_device_unregister(&dev->v4l2_dev);
 
+       cx231xx_unregister_media_device(dev);
+
        usb_put_dev(dev->udev);
 
        /* Mark device as unused */
        clear_bit(dev->devno, &cx231xx_devused);
 }
 
-static void cx231xx_media_device_register(struct cx231xx *dev,
-                                         struct usb_device *udev)
+static int cx231xx_media_device_init(struct cx231xx *dev,
+                                     struct usb_device *udev)
 {
 #ifdef CONFIG_MEDIA_CONTROLLER
        struct media_device *mdev;
-       int ret;
 
-       mdev = kzalloc(sizeof(*mdev), GFP_KERNEL);
+       mdev = media_device_usb_init(udev, dev->board.name);
        if (!mdev)
-               return;
-
-       mdev->dev = dev->dev;
-       strlcpy(mdev->model, dev->board.name, sizeof(mdev->model));
-       if (udev->serial)
-               strlcpy(mdev->serial, udev->serial, sizeof(mdev->serial));
-       strcpy(mdev->bus_info, udev->devpath);
-       mdev->hw_revision = le16_to_cpu(udev->descriptor.bcdDevice);
-       mdev->driver_version = LINUX_VERSION_CODE;
-
-       ret = media_device_register(mdev);
-       if (ret) {
-               dev_err(dev->dev,
-                       "Couldn't create a media device. Error: %d\n",
-                       ret);
-               kfree(mdev);
-               return;
-       }
+               return -ENOMEM;
 
        dev->media_dev = mdev;
 #endif
-}
-
-static void cx231xx_create_media_graph(struct cx231xx *dev)
-{
-#ifdef CONFIG_MEDIA_CONTROLLER
-       struct media_device *mdev = dev->media_dev;
-       struct media_entity *entity;
-       struct media_entity *tuner = NULL, *decoder = 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_V4L2_SUBDEV_DECODER:
-                       decoder = entity;
-                       break;
-               }
-       }
-
-       /* Analog setup, using tuner as a link */
-
-       if (!decoder)
-               return;
-
-       if (tuner)
-               media_entity_create_link(tuner, 0, decoder, 0,
-                                        MEDIA_LNK_FL_ENABLED);
-       media_entity_create_link(decoder, 1, &dev->vdev.entity, 0,
-                                MEDIA_LNK_FL_ENABLED);
-       media_entity_create_link(decoder, 2, &dev->vbi_dev.entity, 0,
-                                MEDIA_LNK_FL_ENABLED);
-#endif
+       return 0;
 }
 
 /*
@@ -1660,8 +1608,12 @@ static int cx231xx_usb_probe(struct usb_interface *interface,
        /* save our data pointer in this interface device */
        usb_set_intfdata(interface, dev);
 
-       /* Register the media controller */
-       cx231xx_media_device_register(dev, udev);
+       /* Initialize the media controller */
+       retval = cx231xx_media_device_init(dev, udev);
+       if (retval) {
+               dev_err(d, "cx231xx_media_device_init failed\n");
+               goto err_media_init;
+       }
 
        /* Create v4l2 device */
 #ifdef CONFIG_MEDIA_CONTROLLER
@@ -1732,9 +1684,18 @@ static int cx231xx_usb_probe(struct usb_interface *interface,
        /* load other modules required */
        request_modules(dev);
 
-       cx231xx_create_media_graph(dev);
+#ifdef CONFIG_MEDIA_CONTROLLER
+       /* Init entities at the Media Controller */
+       cx231xx_v4l2_create_entities(dev);
+
+       retval = v4l2_mc_create_media_graph(dev->media_dev);
+       if (!retval)
+               retval = media_device_register(dev->media_dev);
+#endif
+       if (retval < 0)
+               cx231xx_release_resources(dev);
+       return retval;
 
-       return 0;
 err_video_alt:
        /* cx231xx_uninit_dev: */
        cx231xx_close_extension(dev);
@@ -1746,6 +1707,8 @@ err_video_alt:
 err_init:
        v4l2_device_unregister(&dev->v4l2_dev);
 err_v4l2:
+       cx231xx_unregister_media_device(dev);
+err_media_init:
        usb_set_intfdata(interface, NULL);
 err_if:
        usb_put_dev(udev);