brcm2708: organize kernel patches
[openwrt/staging/chunkeey.git] / target / linux / brcm2708 / patches-4.19 / 950-0716-media-bcm2835-unicam-add-media-controller-support.patch
diff --git a/target/linux/brcm2708/patches-4.19/950-0716-media-bcm2835-unicam-add-media-controller-support.patch b/target/linux/brcm2708/patches-4.19/950-0716-media-bcm2835-unicam-add-media-controller-support.patch
new file mode 100644 (file)
index 0000000..e847212
--- /dev/null
@@ -0,0 +1,128 @@
+From 06cd9857f8faa63321506a75988c475906a32970 Mon Sep 17 00:00:00 2001
+From: Kieran Bingham <kieran.bingham@ideasonboard.com>
+Date: Wed, 20 Mar 2019 12:54:47 +0000
+Subject: [PATCH] media: bcm2835: unicam: add media controller support
+
+Add a media controller device node to represent the Unicam device.
+The attached sensor will be automatically added to the media graph by
+V4L2 core.
+
+Signed-off-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
+---
+ drivers/media/platform/bcm2835/Kconfig        |  2 +-
+ .../media/platform/bcm2835/bcm2835-unicam.c   | 46 ++++++++++++++++++-
+ 2 files changed, 45 insertions(+), 3 deletions(-)
+
+--- a/drivers/media/platform/bcm2835/Kconfig
++++ b/drivers/media/platform/bcm2835/Kconfig
+@@ -2,7 +2,7 @@
+ config VIDEO_BCM2835_UNICAM
+       tristate "Broadcom BCM2835 Unicam video capture driver"
+-      depends on VIDEO_V4L2 && VIDEO_V4L2_SUBDEV_API
++      depends on VIDEO_V4L2 && VIDEO_V4L2_SUBDEV_API && MEDIA_CONTROLLER
+       depends on ARCH_BCM2835 || COMPILE_TEST
+       select VIDEOBUF2_DMA_CONTIG
+       select V4L2_FWNODE
+--- a/drivers/media/platform/bcm2835/bcm2835-unicam.c
++++ b/drivers/media/platform/bcm2835/bcm2835-unicam.c
+@@ -314,6 +314,9 @@ struct unicam_device {
+       struct clk *clock;
+       /* V4l2 device */
+       struct v4l2_device v4l2_dev;
++      struct media_device mdev;
++      struct media_pad pad;
++
+       /* parent device */
+       struct platform_device *pdev;
+       /* subdevice async Notifier */
+@@ -1912,6 +1915,8 @@ static int unicam_probe_complete(struct
+               unicam->v4l2_dev.ctrl_handler = NULL;
+       video_set_drvdata(vdev, unicam);
++      vdev->entity.flags |= MEDIA_ENT_FL_DEFAULT;
++
+       ret = video_register_device(vdev, VFL_TYPE_GRABBER, -1);
+       if (ret) {
+               unicam_err(unicam, "Unable to register video device.\n");
+@@ -1953,6 +1958,16 @@ static int unicam_probe_complete(struct
+               return ret;
+       }
++      ret = media_create_pad_link(&unicam->sensor->entity, 0,
++                                  &unicam->video_dev.entity, 0,
++                                  MEDIA_LNK_FL_ENABLED |
++                                  MEDIA_LNK_FL_IMMUTABLE);
++      if (ret) {
++              unicam_err(unicam, "Unable to create pad links.\n");
++              video_unregister_device(&unicam->video_dev);
++              return ret;
++      }
++
+       return 0;
+ }
+@@ -2155,18 +2170,38 @@ static int unicam_probe(struct platform_
+               return -EINVAL;
+       }
++      unicam->mdev.dev = &pdev->dev;
++      strscpy(unicam->mdev.model, UNICAM_MODULE_NAME,
++              sizeof(unicam->mdev.model));
++      strscpy(unicam->mdev.serial, "", sizeof(unicam->mdev.serial));
++      snprintf(unicam->mdev.bus_info, sizeof(unicam->mdev.bus_info),
++               "platform:%s", pdev->name);
++      unicam->mdev.hw_revision = 1;
++
++      media_entity_pads_init(&unicam->video_dev.entity, 1, &unicam->pad);
++      media_device_init(&unicam->mdev);
++
++      unicam->v4l2_dev.mdev = &unicam->mdev;
++
+       ret = v4l2_device_register(&pdev->dev, &unicam->v4l2_dev);
+       if (ret) {
+               unicam_err(unicam,
+                          "Unable to register v4l2 device.\n");
+-              return ret;
++              goto media_cleanup;
++      }
++
++      ret = media_device_register(&unicam->mdev);
++      if (ret < 0) {
++              unicam_err(unicam,
++                         "Unable to register media-controller device.\n");
++              goto probe_out_v4l2_unregister;
+       }
+       /* Reserve space for the controls */
+       hdl = &unicam->ctrl_handler;
+       ret = v4l2_ctrl_handler_init(hdl, 16);
+       if (ret < 0)
+-              goto probe_out_v4l2_unregister;
++              goto media_unregister;
+       unicam->v4l2_dev.ctrl_handler = hdl;
+       /* set the driver data in platform device */
+@@ -2185,8 +2220,13 @@ static int unicam_probe(struct platform_
+ free_hdl:
+       v4l2_ctrl_handler_free(hdl);
++media_unregister:
++      media_device_unregister(&unicam->mdev);
+ probe_out_v4l2_unregister:
+       v4l2_device_unregister(&unicam->v4l2_dev);
++media_cleanup:
++      media_device_cleanup(&unicam->mdev);
++
+       return ret;
+ }
+@@ -2204,6 +2244,8 @@ static int unicam_remove(struct platform
+       video_unregister_device(&unicam->video_dev);
+       if (unicam->sensor_config)
+               v4l2_subdev_free_pad_config(unicam->sensor_config);
++      media_device_unregister(&unicam->mdev);
++      media_device_cleanup(&unicam->mdev);
+       return 0;
+ }