aboutsummaryrefslogtreecommitdiffstats
path: root/target/linux/bcm27xx/patches-4.19/950-0684-staging-bcm2835-codec-add-media-controller-support.patch
blob: a42fa7dfe1cd4be9279f06e7240f5d37be94d247 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
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;
 }