brcm2708: organize kernel patches
[openwrt/staging/wigyori.git] / target / linux / brcm2708 / patches-4.19 / 950-0714-staging-bcm2835-codec-add-media-controller-support.patch
diff --git a/target/linux/brcm2708/patches-4.19/950-0714-staging-bcm2835-codec-add-media-controller-support.patch b/target/linux/brcm2708/patches-4.19/950-0714-staging-bcm2835-codec-add-media-controller-support.patch
new file mode 100644 (file)
index 0000000..a42fa7d
--- /dev/null
@@ -0,0 +1,163 @@
+From d1ceb85b7c6c7c3eec8b424e0172c29e93a570f2 Mon Sep 17 00:00:00 2001
+From: Kieran Bingham <kieran.bingham@ideasonboard.com>
+Date: Wed, 20 Mar 2019 12:54:15 +0000
+Subject: [PATCH] staging: bcm2835-codec: add media controller support
+
+Provide a single media device to contain all of the bcm2835_codec
+devices created.
+
+Signed-off-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
+---
+ .../vc04_services/bcm2835-codec/Kconfig       |  2 +-
+ .../bcm2835-codec/bcm2835-v4l2-codec.c        | 41 +++++++++++++++++--
+ 2 files changed, 38 insertions(+), 5 deletions(-)
+
+--- a/drivers/staging/vc04_services/bcm2835-codec/Kconfig
++++ b/drivers/staging/vc04_services/bcm2835-codec/Kconfig
+@@ -1,6 +1,6 @@
+ config VIDEO_CODEC_BCM2835
+       tristate "BCM2835 Video codec support"
+-      depends on MEDIA_SUPPORT
++      depends on MEDIA_SUPPORT && MEDIA_CONTROLLER
+       depends on VIDEO_V4L2 && (ARCH_BCM2835 || COMPILE_TEST)
+       select BCM2835_VCHIQ_MMAL
+       select VIDEOBUF2_DMA_CONTIG
+--- a/drivers/staging/vc04_services/bcm2835-codec/bcm2835-v4l2-codec.c
++++ b/drivers/staging/vc04_services/bcm2835-codec/bcm2835-v4l2-codec.c
+@@ -458,6 +458,7 @@ struct bcm2835_codec_ctx {
+ struct bcm2835_codec_driver {
+       struct platform_device *pdev;
++      struct media_device     mdev;
+       struct bcm2835_codec_dev *encode;
+       struct bcm2835_codec_dev *decode;
+@@ -2596,6 +2597,7 @@ static int bcm2835_codec_create(struct b
+       struct platform_device *pdev = drv->pdev;
+       struct bcm2835_codec_dev *dev;
+       struct video_device *vfd;
++      int function;
+       int video_nr;
+       int ret;
+@@ -2615,18 +2617,21 @@ static int bcm2835_codec_create(struct b
+       if (ret)
+               goto vchiq_finalise;
+-      ret = v4l2_device_register(&pdev->dev, &dev->v4l2_dev);
+-      if (ret)
+-              goto vchiq_finalise;
+-
+       atomic_set(&dev->num_inst, 0);
+       mutex_init(&dev->dev_mutex);
++      /* Initialise the video device */
+       dev->vfd = bcm2835_codec_videodev;
++
+       vfd = &dev->vfd;
+       vfd->lock = &dev->dev_mutex;
+       vfd->v4l2_dev = &dev->v4l2_dev;
+       vfd->device_caps = V4L2_CAP_VIDEO_M2M_MPLANE | V4L2_CAP_STREAMING;
++      vfd->v4l2_dev->mdev = &drv->mdev;
++
++      ret = v4l2_device_register(&pdev->dev, &dev->v4l2_dev);
++      if (ret)
++              goto vchiq_finalise;
+       switch (role) {
+       case DECODE:
+@@ -2634,11 +2639,13 @@ static int bcm2835_codec_create(struct b
+               v4l2_disable_ioctl(vfd, VIDIOC_TRY_ENCODER_CMD);
+               v4l2_disable_ioctl(vfd, VIDIOC_S_PARM);
+               v4l2_disable_ioctl(vfd, VIDIOC_G_PARM);
++              function = MEDIA_ENT_F_PROC_VIDEO_DECODER;
+               video_nr = decode_video_nr;
+               break;
+       case ENCODE:
+               v4l2_disable_ioctl(vfd, VIDIOC_DECODER_CMD);
+               v4l2_disable_ioctl(vfd, VIDIOC_TRY_DECODER_CMD);
++              function = MEDIA_ENT_F_PROC_VIDEO_ENCODER;
+               video_nr = encode_video_nr;
+               break;
+       case ISP:
+@@ -2648,6 +2655,7 @@ static int bcm2835_codec_create(struct b
+               v4l2_disable_ioctl(vfd, VIDIOC_TRY_DECODER_CMD);
+               v4l2_disable_ioctl(vfd, VIDIOC_S_PARM);
+               v4l2_disable_ioctl(vfd, VIDIOC_G_PARM);
++              function = MEDIA_ENT_F_PROC_VIDEO_SCALER;
+               video_nr = isp_video_nr;
+               break;
+       default:
+@@ -2676,6 +2684,10 @@ static int bcm2835_codec_create(struct b
+               goto err_m2m;
+       }
++      ret = v4l2_m2m_register_media_controller(dev->m2m_dev, vfd, function);
++      if (ret)
++              goto err_m2m;
++
+       v4l2_info(&dev->v4l2_dev, "Loaded V4L2 %s\n",
+                 roles[role]);
+       return 0;
+@@ -2697,6 +2709,7 @@ static int bcm2835_codec_destroy(struct
+       v4l2_info(&dev->v4l2_dev, "Removing " MEM2MEM_NAME ", %s\n",
+                 roles[dev->role]);
++      v4l2_m2m_unregister_media_controller(dev->m2m_dev);
+       v4l2_m2m_release(dev->m2m_dev);
+       video_unregister_device(&dev->vfd);
+       v4l2_device_unregister(&dev->v4l2_dev);
+@@ -2708,6 +2721,7 @@ static int bcm2835_codec_destroy(struct
+ static int bcm2835_codec_probe(struct platform_device *pdev)
+ {
+       struct bcm2835_codec_driver *drv;
++      struct media_device *mdev;
+       int ret = 0;
+       drv = devm_kzalloc(&pdev->dev, sizeof(*drv), GFP_KERNEL);
+@@ -2715,6 +2729,17 @@ static int bcm2835_codec_probe(struct pl
+               return -ENOMEM;
+       drv->pdev = pdev;
++      mdev = &drv->mdev;
++      mdev->dev = &pdev->dev;
++
++      strscpy(mdev->model, bcm2835_codec_videodev.name, sizeof(mdev->model));
++      strscpy(mdev->serial, "0000", sizeof(mdev->serial));
++      snprintf(mdev->bus_info, sizeof(mdev->bus_info), "platform:%s",
++               pdev->name);
++
++      /* This should return the vgencmd version information or such .. */
++      mdev->hw_revision = 1;
++      media_device_init(mdev);
+       ret = bcm2835_codec_create(drv, &drv->decode, DECODE);
+       if (ret)
+@@ -2728,6 +2753,10 @@ static int bcm2835_codec_probe(struct pl
+       if (ret)
+               goto out;
++      /* Register the media device node */
++      if (media_device_register(mdev) < 0)
++              goto out;
++
+       platform_set_drvdata(pdev, drv);
+       return 0;
+@@ -2748,12 +2777,16 @@ static int bcm2835_codec_remove(struct p
+ {
+       struct bcm2835_codec_driver *drv = platform_get_drvdata(pdev);
++      media_device_unregister(&drv->mdev);
++
+       bcm2835_codec_destroy(drv->isp);
+       bcm2835_codec_destroy(drv->encode);
+       bcm2835_codec_destroy(drv->decode);
++      media_device_cleanup(&drv->mdev);
++
+       return 0;
+ }