You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
164 lines
4.9 KiB
Diff
164 lines
4.9 KiB
Diff
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;
|
|
}
|
|
|