brcm2708: switch to linux 4.9
[lede.git] / target / linux / brcm2708 / patches-4.4 / 0300-V4L2-Request-maximum-resolution-from-GPU.patch
1 From 4f0614de030f2a75be22a8f7ebc298e8260021cf Mon Sep 17 00:00:00 2001
2 From: Dave Stevenson <6by9@users.noreply.github.com>
3 Date: Sat, 16 Apr 2016 23:09:54 +0100
4 Subject: [PATCH] V4L2: Request maximum resolution from GPU
5
6 Get resolution information about the sensors from the GPU
7 and advertise it correctly.
8
9 Signed-off-by: Dave Stevenson <6by9@users.noreply.github.com>
10 ---
11  drivers/media/platform/bcm2835/bcm2835-camera.c | 59 +++++++++++++++++--------
12  drivers/media/platform/bcm2835/bcm2835-camera.h |  3 +-
13  2 files changed, 43 insertions(+), 19 deletions(-)
14
15 --- a/drivers/media/platform/bcm2835/bcm2835-camera.c
16 +++ b/drivers/media/platform/bcm2835/bcm2835-camera.c
17 @@ -38,8 +38,6 @@
18  #define BM2835_MMAL_MODULE_NAME "bcm2835-v4l2"
19  #define MIN_WIDTH 16
20  #define MIN_HEIGHT 16
21 -#define MAX_WIDTH 2592
22 -#define MAX_HEIGHT 1944
23  #define MIN_BUFFER_SIZE (80*1024)
24  
25  #define MAX_VIDEO_MODE_WIDTH 1280
26 @@ -729,11 +727,11 @@ static int vidioc_try_fmt_vid_overlay(st
27         f->fmt.win.clipcount = 0;
28         f->fmt.win.bitmap = NULL;
29  
30 -       v4l_bound_align_image(&f->fmt.win.w.width, MIN_WIDTH, MAX_WIDTH, 1,
31 -                             &f->fmt.win.w.height, MIN_HEIGHT, MAX_HEIGHT,
32 +       v4l_bound_align_image(&f->fmt.win.w.width, MIN_WIDTH, dev->max_width, 1,
33 +                             &f->fmt.win.w.height, MIN_HEIGHT, dev->max_height,
34                               1, 0);
35 -       v4l_bound_align_image(&f->fmt.win.w.left, MIN_WIDTH, MAX_WIDTH, 1,
36 -                             &f->fmt.win.w.top, MIN_HEIGHT, MAX_HEIGHT,
37 +       v4l_bound_align_image(&f->fmt.win.w.left, MIN_WIDTH, dev->max_width, 1,
38 +                             &f->fmt.win.w.top, MIN_HEIGHT, dev->max_height,
39                               1, 0);
40  
41         v4l2_dbg(1, bcm2835_v4l2_debug, &dev->v4l2_dev,
42 @@ -961,8 +959,9 @@ static int vidioc_try_fmt_vid_cap(struct
43                 "Clipping/aligning %dx%d format %08X\n",
44                 f->fmt.pix.width, f->fmt.pix.height, f->fmt.pix.pixelformat);
45  
46 -       v4l_bound_align_image(&f->fmt.pix.width, MIN_WIDTH, MAX_WIDTH, 1,
47 -                             &f->fmt.pix.height, MIN_HEIGHT, MAX_HEIGHT, 1, 0);
48 +       v4l_bound_align_image(&f->fmt.pix.width, MIN_WIDTH, dev->max_width, 1,
49 +                             &f->fmt.pix.height, MIN_HEIGHT, dev->max_height,
50 +                             1, 0);
51         f->fmt.pix.bytesperline = f->fmt.pix.width * mfmt->ybbp;
52  
53         /* Image buffer has to be padded to allow for alignment, even though
54 @@ -1301,9 +1300,10 @@ static int vidioc_s_fmt_vid_cap(struct f
55  int vidioc_enum_framesizes(struct file *file, void *fh,
56                            struct v4l2_frmsizeenum *fsize)
57  {
58 +       struct bm2835_mmal_dev *dev = video_drvdata(file);
59         static const struct v4l2_frmsize_stepwise sizes = {
60 -               MIN_WIDTH, MAX_WIDTH, 2,
61 -               MIN_HEIGHT, MAX_HEIGHT, 2
62 +               MIN_WIDTH, 0, 2,
63 +               MIN_HEIGHT, 0, 2
64         };
65         int i;
66  
67 @@ -1316,6 +1316,8 @@ int vidioc_enum_framesizes(struct file *
68                 return -EINVAL;
69         fsize->type = V4L2_FRMSIZE_TYPE_STEPWISE;
70         fsize->stepwise = sizes;
71 +       fsize->stepwise.max_width = dev->max_width;
72 +       fsize->stepwise.max_height = dev->max_height;
73         return 0;
74  }
75  
76 @@ -1323,6 +1325,7 @@ int vidioc_enum_framesizes(struct file *
77  static int vidioc_enum_frameintervals(struct file *file, void *priv,
78                                              struct v4l2_frmivalenum *fival)
79  {
80 +       struct bm2835_mmal_dev *dev = video_drvdata(file);
81         int i;
82  
83         if (fival->index)
84 @@ -1335,8 +1338,8 @@ static int vidioc_enum_frameintervals(st
85                 return -EINVAL;
86  
87         /* regarding width & height - we support any within range */
88 -       if (fival->width < MIN_WIDTH || fival->width > MAX_WIDTH ||
89 -           fival->height < MIN_HEIGHT || fival->height > MAX_HEIGHT)
90 +       if (fival->width < MIN_WIDTH || fival->width > dev->max_width ||
91 +           fival->height < MIN_HEIGHT || fival->height > dev->max_height)
92                 return -EINVAL;
93  
94         fival->type = V4L2_FRMIVAL_TYPE_CONTINUOUS;
95 @@ -1499,12 +1502,17 @@ static struct video_device vdev_template
96         .release = video_device_release_empty,
97  };
98  
99 -static int get_num_cameras(struct vchiq_mmal_instance *instance)
100 +/* Returns the number of cameras, and also the max resolution supported
101 + * by those cameras.
102 + */
103 +static int get_num_cameras(struct vchiq_mmal_instance *instance,
104 +       unsigned int resolutions[][2], int num_resolutions)
105  {
106         int ret;
107         struct vchiq_mmal_component  *cam_info_component;
108         struct mmal_parameter_camera_info_t cam_info = {0};
109         int param_size = sizeof(cam_info);
110 +       int i;
111  
112         /* create a camera_info component */
113         ret = vchiq_mmal_component_init(instance, "camera_info",
114 @@ -1520,6 +1528,14 @@ static int get_num_cameras(struct vchiq_
115                                           &param_size)) {
116                 pr_info("Failed to get camera info\n");
117         }
118 +       for (i = 0;
119 +            i < (cam_info.num_cameras > num_resolutions ?
120 +                       cam_info.num_cameras :
121 +                       num_resolutions);
122 +            i++) {
123 +               resolutions[i][0] = cam_info.cameras[i].max_width;
124 +               resolutions[i][1] = cam_info.cameras[i].max_height;
125 +       }
126  
127         vchiq_mmal_component_finalise(instance,
128                                       cam_info_component);
129 @@ -1528,12 +1544,13 @@ static int get_num_cameras(struct vchiq_
130  }
131  
132  static int set_camera_parameters(struct vchiq_mmal_instance *instance,
133 -                                struct vchiq_mmal_component *camera)
134 +                                struct vchiq_mmal_component *camera,
135 +                                struct bm2835_mmal_dev *dev)
136  {
137         int ret;
138         struct mmal_parameter_camera_config cam_config = {
139 -               .max_stills_w = MAX_WIDTH,
140 -               .max_stills_h = MAX_HEIGHT,
141 +               .max_stills_w = dev->max_width,
142 +               .max_stills_h = dev->max_height,
143                 .stills_yuv422 = 1,
144                 .one_shot_stills = 1,
145                 .max_preview_video_w = (max_video_width > 1920) ?
146 @@ -1576,7 +1593,8 @@ static int __init mmal_init(struct bm283
147         }
148  
149         ret = set_camera_parameters(dev->instance,
150 -                                   dev->component[MMAL_COMPONENT_CAMERA]);
151 +                                   dev->component[MMAL_COMPONENT_CAMERA],
152 +                                   dev);
153         if (ret < 0)
154                 goto unreg_camera;
155  
156 @@ -1838,12 +1856,15 @@ static int __init bm2835_mmal_init(void)
157         int camera;
158         unsigned int num_cameras;
159         struct vchiq_mmal_instance *instance;
160 +       unsigned int resolutions[MAX_BCM2835_CAMERAS][2];
161  
162         ret = vchiq_mmal_init(&instance);
163         if (ret < 0)
164                 return ret;
165  
166 -       num_cameras = get_num_cameras(instance);
167 +       num_cameras = get_num_cameras(instance,
168 +                                     resolutions,
169 +                                     MAX_BCM2835_CAMERAS);
170         if (num_cameras > MAX_BCM2835_CAMERAS)
171                 num_cameras = MAX_BCM2835_CAMERAS;
172  
173 @@ -1853,6 +1874,8 @@ static int __init bm2835_mmal_init(void)
174                         return -ENOMEM;
175  
176                 dev->camera_num = camera;
177 +               dev->max_width = resolutions[camera][0];
178 +               dev->max_height = resolutions[camera][1];
179  
180                 /* setup device defaults */
181                 dev->overlay.w.left = 150;
182 --- a/drivers/media/platform/bcm2835/bcm2835-camera.h
183 +++ b/drivers/media/platform/bcm2835/bcm2835-camera.h
184 @@ -107,7 +107,8 @@ struct bm2835_mmal_dev {
185         } capture;
186  
187         unsigned int camera_num;
188 -
189 +       unsigned int max_width;
190 +       unsigned int max_height;
191  };
192  
193  int bm2835_mmal_init_controls(