aboutsummaryrefslogtreecommitdiffstats
path: root/target/linux/brcm2708/patches-4.4/0300-V4L2-Request-maximum-resolution-from-GPU.patch
blob: edd95a18655d1c1fa3f1ae2831c12e1ab6b421f3 (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
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
From 4f0614de030f2a75be22a8f7ebc298e8260021cf Mon Sep 17 00:00:00 2001
From: Dave Stevenson <6by9@users.noreply.github.com>
Date: Sat, 16 Apr 2016 23:09:54 +0100
Subject: [PATCH] V4L2: Request maximum resolution from GPU

Get resolution information about the sensors from the GPU
and advertise it correctly.

Signed-off-by: Dave Stevenson <6by9@users.noreply.github.com>
---
 drivers/media/platform/bcm2835/bcm2835-camera.c | 59 +++++++++++++++++--------
 drivers/media/platform/bcm2835/bcm2835-camera.h |  3 +-
 2 files changed, 43 insertions(+), 19 deletions(-)

--- a/drivers/media/platform/bcm2835/bcm2835-camera.c
+++ b/drivers/media/platform/bcm2835/bcm2835-camera.c
@@ -38,8 +38,6 @@
 #define BM2835_MMAL_MODULE_NAME "bcm2835-v4l2"
 #define MIN_WIDTH 16
 #define MIN_HEIGHT 16
-#define MAX_WIDTH 2592
-#define MAX_HEIGHT 1944
 #define MIN_BUFFER_SIZE (80*1024)
 
 #define MAX_VIDEO_MODE_WIDTH 1280
@@ -729,11 +727,11 @@ static int vidioc_try_fmt_vid_overlay(st
 	f->fmt.win.clipcount = 0;
 	f->fmt.win.bitmap = NULL;
 
-	v4l_bound_align_image(&f->fmt.win.w.width, MIN_WIDTH, MAX_WIDTH, 1,
-			      &f->fmt.win.w.height, MIN_HEIGHT, MAX_HEIGHT,
+	v4l_bound_align_image(&f->fmt.win.w.width, MIN_WIDTH, dev->max_width, 1,
+			      &f->fmt.win.w.height, MIN_HEIGHT, dev->max_height,
 			      1, 0);
-	v4l_bound_align_image(&f->fmt.win.w.left, MIN_WIDTH, MAX_WIDTH, 1,
-			      &f->fmt.win.w.top, MIN_HEIGHT, MAX_HEIGHT,
+	v4l_bound_align_image(&f->fmt.win.w.left, MIN_WIDTH, dev->max_width, 1,
+			      &f->fmt.win.w.top, MIN_HEIGHT, dev->max_height,
 			      1, 0);
 
 	v4l2_dbg(1, bcm2835_v4l2_debug, &dev->v4l2_dev,
@@ -961,8 +959,9 @@ static int vidioc_try_fmt_vid_cap(struct
 		"Clipping/aligning %dx%d format %08X\n",
 		f->fmt.pix.width, f->fmt.pix.height, f->fmt.pix.pixelformat);
 
-	v4l_bound_align_image(&f->fmt.pix.width, MIN_WIDTH, MAX_WIDTH, 1,
-			      &f->fmt.pix.height, MIN_HEIGHT, MAX_HEIGHT, 1, 0);
+	v4l_bound_align_image(&f->fmt.pix.width, MIN_WIDTH, dev->max_width, 1,
+			      &f->fmt.pix.height, MIN_HEIGHT, dev->max_height,
+			      1, 0);
 	f->fmt.pix.bytesperline = f->fmt.pix.width * mfmt->ybbp;
 
 	/* Image buffer has to be padded to allow for alignment, even though
@@ -1301,9 +1300,10 @@ static int vidioc_s_fmt_vid_cap(struct f
 int vidioc_enum_framesizes(struct file *file, void *fh,
 			   struct v4l2_frmsizeenum *fsize)
 {
+	struct bm2835_mmal_dev *dev = video_drvdata(file);
 	static const struct v4l2_frmsize_stepwise sizes = {
-		MIN_WIDTH, MAX_WIDTH, 2,
-		MIN_HEIGHT, MAX_HEIGHT, 2
+		MIN_WIDTH, 0, 2,
+		MIN_HEIGHT, 0, 2
 	};
 	int i;
 
@@ -1316,6 +1316,8 @@ int vidioc_enum_framesizes(struct file *
 		return -EINVAL;
 	fsize->type = V4L2_FRMSIZE_TYPE_STEPWISE;
 	fsize->stepwise = sizes;
+	fsize->stepwise.max_width = dev->max_width;
+	fsize->stepwise.max_height = dev->max_height;
 	return 0;
 }
 
@@ -1323,6 +1325,7 @@ int vidioc_enum_framesizes(struct file *
 static int vidioc_enum_frameintervals(struct file *file, void *priv,
 					     struct v4l2_frmivalenum *fival)
 {
+	struct bm2835_mmal_dev *dev = video_drvdata(file);
 	int i;
 
 	if (fival->index)
@@ -1335,8 +1338,8 @@ static int vidioc_enum_frameintervals(st
 		return -EINVAL;
 
 	/* regarding width & height - we support any within range */
-	if (fival->width < MIN_WIDTH || fival->width > MAX_WIDTH ||
-	    fival->height < MIN_HEIGHT || fival->height > MAX_HEIGHT)
+	if (fival->width < MIN_WIDTH || fival->width > dev->max_width ||
+	    fival->height < MIN_HEIGHT || fival->height > dev->max_height)
 		return -EINVAL;
 
 	fival->type = V4L2_FRMIVAL_TYPE_CONTINUOUS;
@@ -1499,12 +1502,17 @@ static struct video_device vdev_template
 	.release = video_device_release_empty,
 };
 
-static int get_num_cameras(struct vchiq_mmal_instance *instance)
+/* Returns the number of cameras, and also the max resolution supported
+ * by those cameras.
+ */
+static int get_num_cameras(struct vchiq_mmal_instance *instance,
+	unsigned int resolutions[][2], int num_resolutions)
 {
 	int ret;
 	struct vchiq_mmal_component  *cam_info_component;
 	struct mmal_parameter_camera_info_t cam_info = {0};
 	int param_size = sizeof(cam_info);
+	int i;
 
 	/* create a camera_info component */
 	ret = vchiq_mmal_component_init(instance, "camera_info",
@@ -1520,6 +1528,14 @@ static int get_num_cameras(struct vchiq_
 					  &param_size)) {
 		pr_info("Failed to get camera info\n");
 	}
+	for (i = 0;
+	     i < (cam_info.num_cameras > num_resolutions ?
+			cam_info.num_cameras :
+			num_resolutions);
+	     i++) {
+		resolutions[i][0] = cam_info.cameras[i].max_width;
+		resolutions[i][1] = cam_info.cameras[i].max_height;
+	}
 
 	vchiq_mmal_component_finalise(instance,
 				      cam_info_component);
@@ -1528,12 +1544,13 @@ static int get_num_cameras(struct vchiq_
 }
 
 static int set_camera_parameters(struct vchiq_mmal_instance *instance,
-				 struct vchiq_mmal_component *camera)
+				 struct vchiq_mmal_component *camera,
+				 struct bm2835_mmal_dev *dev)
 {
 	int ret;
 	struct mmal_parameter_camera_config cam_config = {
-		.max_stills_w = MAX_WIDTH,
-		.max_stills_h = MAX_HEIGHT,
+		.max_stills_w = dev->max_width,
+		.max_stills_h = dev->max_height,
 		.stills_yuv422 = 1,
 		.one_shot_stills = 1,
 		.max_preview_video_w = (max_video_width > 1920) ?
@@ -1576,7 +1593,8 @@ static int __init mmal_init(struct bm283
 	}
 
 	ret = set_camera_parameters(dev->instance,
-				    dev->component[MMAL_COMPONENT_CAMERA]);
+				    dev->component[MMAL_COMPONENT_CAMERA],
+				    dev);
 	if (ret < 0)
 		goto unreg_camera;
 
@@ -1838,12 +1856,15 @@ static int __init bm2835_mmal_init(void)
 	int camera;
 	unsigned int num_cameras;
 	struct vchiq_mmal_instance *instance;
+	unsigned int resolutions[MAX_BCM2835_CAMERAS][2];
 
 	ret = vchiq_mmal_init(&instance);
 	if (ret < 0)
 		return ret;
 
-	num_cameras = get_num_cameras(instance);
+	num_cameras = get_num_cameras(instance,
+				      resolutions,
+				      MAX_BCM2835_CAMERAS);
 	if (num_cameras > MAX_BCM2835_CAMERAS)
 		num_cameras = MAX_BCM2835_CAMERAS;
 
@@ -1853,6 +1874,8 @@ static int __init bm2835_mmal_init(void)
 			return -ENOMEM;
 
 		dev->camera_num = camera;
+		dev->max_width = resolutions[camera][0];
+		dev->max_height = resolutions[camera][1];
 
 		/* setup device defaults */
 		dev->overlay.w.left = 150;
--- a/drivers/media/platform/bcm2835/bcm2835-camera.h
+++ b/drivers/media/platform/bcm2835/bcm2835-camera.h
@@ -107,7 +107,8 @@ struct bm2835_mmal_dev {
 	} capture;
 
 	unsigned int camera_num;
-
+	unsigned int max_width;
+	unsigned int max_height;
 };
 
 int bm2835_mmal_init_controls(