From d1ceb85b7c6c7c3eec8b424e0172c29e93a570f2 Mon Sep 17 00:00:00 2001 From: Kieran Bingham 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 --- .../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; }