brcm2708: update against latest rpi-3.10.y branch
[openwrt.git] / target / linux / brcm2708 / patches-3.10 / 0136-V4L2-Add-support-for-frame-rate-control.patch
1 From 980348ac7301c266ddbed9256ad9835cbda6e719 Mon Sep 17 00:00:00 2001
2 From: Dave Stevenson <dsteve@broadcom.com>
3 Date: Fri, 13 Dec 2013 15:54:13 +0000
4 Subject: [PATCH 136/174] V4L2: Add support for frame rate control.
5
6 Add support for frame rate (or time per frame as V4L2
7 inverts it) control via s_parm.
8
9 Signed-off-by: Dave Stevenson <dsteve@broadcom.com>
10 ---
11  drivers/media/platform/bcm2835/bcm2835-camera.c  | 115 +++++++++++++++++++++--
12  drivers/media/platform/bcm2835/bcm2835-camera.h  |   4 +-
13  drivers/media/platform/bcm2835/controls.c        |   5 +-
14  drivers/media/platform/bcm2835/mmal-parameters.h |   5 +
15  4 files changed, 116 insertions(+), 13 deletions(-)
16
17 --- a/drivers/media/platform/bcm2835/bcm2835-camera.c
18 +++ b/drivers/media/platform/bcm2835/bcm2835-camera.c
19 @@ -55,6 +55,15 @@ MODULE_PARM_DESC(bcm2835_v4l2_debug, "De
20  
21  static struct bm2835_mmal_dev *gdev;   /* global device data */
22  
23 +#define FPS_MIN 1
24 +#define FPS_MAX 30
25 +
26 +/* timeperframe: min/max and default */
27 +static const struct v4l2_fract
28 +       tpf_min     = {.numerator = 1,          .denominator = FPS_MAX},
29 +       tpf_max     = {.numerator = 1,          .denominator = FPS_MIN},
30 +       tpf_default = {.numerator = 1000,       .denominator = 30000};
31 +
32  /* video formats */
33  static struct mmal_fmt formats[] = {
34         {
35 @@ -869,8 +878,10 @@ static int mmal_setup_components(struct
36         camera_port->es.video.crop.y = 0;
37         camera_port->es.video.crop.width = f->fmt.pix.width;
38         camera_port->es.video.crop.height = f->fmt.pix.height;
39 -       camera_port->es.video.frame_rate.num = 30;
40 -       camera_port->es.video.frame_rate.den = 1;
41 +       camera_port->es.video.frame_rate.num =
42 +                       dev->capture.timeperframe.denominator;
43 +       camera_port->es.video.frame_rate.den =
44 +                       dev->capture.timeperframe.numerator;
45  
46         ret = vchiq_mmal_port_set_format(dev->instance, camera_port);
47  
48 @@ -1064,6 +1075,90 @@ static int vidioc_s_fmt_vid_cap(struct f
49         return ret;
50  }
51  
52 +/* timeperframe is arbitrary and continous */
53 +static int vidioc_enum_frameintervals(struct file *file, void *priv,
54 +                                            struct v4l2_frmivalenum *fival)
55 +{
56 +       if (fival->index)
57 +               return -EINVAL;
58 +
59 +       /* regarding width & height - we support any */
60 +
61 +       fival->type = V4L2_FRMIVAL_TYPE_CONTINUOUS;
62 +
63 +       /* fill in stepwise (step=1.0 is requred by V4L2 spec) */
64 +       fival->stepwise.min  = tpf_min;
65 +       fival->stepwise.max  = tpf_max;
66 +       fival->stepwise.step = (struct v4l2_fract) {1, 1};
67 +
68 +       return 0;
69 +}
70 +
71 +static int vidioc_g_parm(struct file *file, void *priv,
72 +                         struct v4l2_streamparm *parm)
73 +{
74 +       struct bm2835_mmal_dev *dev = video_drvdata(file);
75 +
76 +       if (parm->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
77 +               return -EINVAL;
78 +
79 +       parm->parm.capture.capability   = V4L2_CAP_TIMEPERFRAME;
80 +       parm->parm.capture.timeperframe = dev->capture.timeperframe;
81 +       parm->parm.capture.readbuffers  = 1;
82 +       return 0;
83 +}
84 +
85 +#define FRACT_CMP(a, OP, b)    \
86 +       ((u64)(a).numerator * (b).denominator  OP  \
87 +        (u64)(b).numerator * (a).denominator)
88 +
89 +static int vidioc_s_parm(struct file *file, void *priv,
90 +                         struct v4l2_streamparm *parm)
91 +{
92 +       struct bm2835_mmal_dev *dev = video_drvdata(file);
93 +       struct v4l2_fract tpf;
94 +       struct mmal_parameter_rational fps_param;
95 +       int ret;
96 +
97 +       if (parm->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
98 +               return -EINVAL;
99 +
100 +       tpf = parm->parm.capture.timeperframe;
101 +
102 +       /* tpf: {*, 0} resets timing; clip to [min, max]*/
103 +       tpf = tpf.denominator ? tpf : tpf_default;
104 +       tpf = FRACT_CMP(tpf, <, tpf_min) ? tpf_min : tpf;
105 +       tpf = FRACT_CMP(tpf, >, tpf_max) ? tpf_max : tpf;
106 +
107 +       dev->capture.timeperframe = tpf;
108 +       parm->parm.capture.timeperframe = tpf;
109 +       parm->parm.capture.readbuffers  = 1;
110 +
111 +       fps_param.num = dev->capture.timeperframe.denominator;
112 +       fps_param.den = dev->capture.timeperframe.numerator;
113 +       ret = vchiq_mmal_port_parameter_set(dev->instance,
114 +                                     &dev->component[MMAL_COMPONENT_CAMERA]->
115 +                                       output[MMAL_CAMERA_PORT_PREVIEW],
116 +                                     MMAL_PARAMETER_VIDEO_FRAME_RATE,
117 +                                     &fps_param, sizeof(fps_param));
118 +       ret += vchiq_mmal_port_parameter_set(dev->instance,
119 +                                     &dev->component[MMAL_COMPONENT_CAMERA]->
120 +                                       output[MMAL_CAMERA_PORT_VIDEO],
121 +                                     MMAL_PARAMETER_VIDEO_FRAME_RATE,
122 +                                     &fps_param, sizeof(fps_param));
123 +       ret += vchiq_mmal_port_parameter_set(dev->instance,
124 +                                     &dev->component[MMAL_COMPONENT_CAMERA]->
125 +                                       output[MMAL_CAMERA_PORT_CAPTURE],
126 +                                     MMAL_PARAMETER_VIDEO_FRAME_RATE,
127 +                                     &fps_param, sizeof(fps_param));
128 +       if (ret)
129 +               v4l2_dbg(0, bcm2835_v4l2_debug, &dev->v4l2_dev,
130 +                "Failed to set fps ret %d\n",
131 +                ret);
132 +
133 +       return 0;
134 +}
135 +
136  static const struct v4l2_ioctl_ops camera0_ioctl_ops = {
137         /* overlay */
138         .vidioc_enum_fmt_vid_overlay = vidioc_enum_fmt_vid_overlay,
139 @@ -1092,6 +1187,9 @@ static const struct v4l2_ioctl_ops camer
140         .vidioc_querybuf = vb2_ioctl_querybuf,
141         .vidioc_qbuf = vb2_ioctl_qbuf,
142         .vidioc_dqbuf = vb2_ioctl_dqbuf,
143 +       .vidioc_enum_frameintervals = vidioc_enum_frameintervals,
144 +       .vidioc_g_parm        = vidioc_g_parm,
145 +       .vidioc_s_parm        = vidioc_s_parm,
146         .vidioc_streamon = vb2_ioctl_streamon,
147         .vidioc_streamoff = vb2_ioctl_streamoff,
148  
149 @@ -1184,8 +1282,10 @@ static int __init mmal_init(struct bm283
150         format->es->video.crop.y = 0;
151         format->es->video.crop.width = 1024;
152         format->es->video.crop.height = 768;
153 -       format->es->video.frame_rate.num = PREVIEW_FRAME_RATE_NUM;
154 -       format->es->video.frame_rate.den = PREVIEW_FRAME_RATE_DEN;
155 +       format->es->video.frame_rate.num =
156 +                       dev->capture.timeperframe.denominator;
157 +       format->es->video.frame_rate.den =
158 +                       dev->capture.timeperframe.numerator;
159  
160         format =
161             &dev->component[MMAL_COMPONENT_CAMERA]->
162 @@ -1200,8 +1300,10 @@ static int __init mmal_init(struct bm283
163         format->es->video.crop.y = 0;
164         format->es->video.crop.width = 1024;
165         format->es->video.crop.height = 768;
166 -       format->es->video.frame_rate.num = PREVIEW_FRAME_RATE_NUM;
167 -       format->es->video.frame_rate.den = PREVIEW_FRAME_RATE_DEN;
168 +       format->es->video.frame_rate.num =
169 +                       dev->capture.timeperframe.denominator;
170 +       format->es->video.frame_rate.den =
171 +                       dev->capture.timeperframe.numerator;
172  
173         format =
174             &dev->component[MMAL_COMPONENT_CAMERA]->
175 @@ -1222,6 +1324,7 @@ static int __init mmal_init(struct bm283
176         dev->capture.height = format->es->video.height;
177         dev->capture.fmt = &formats[0];
178         dev->capture.encode_component = NULL;
179 +       dev->capture.timeperframe = tpf_default;
180  
181         /* get the preview component ready */
182         ret = vchiq_mmal_component_init(
183 --- a/drivers/media/platform/bcm2835/bcm2835-camera.h
184 +++ b/drivers/media/platform/bcm2835/bcm2835-camera.h
185 @@ -32,9 +32,6 @@ enum {
186         MMAL_CAMERA_PORT_COUNT
187  };
188  
189 -#define PREVIEW_FRAME_RATE_NUM 30
190 -#define PREVIEW_FRAME_RATE_DEN 1
191 -
192  #define PREVIEW_LAYER      2
193  
194  extern int bcm2835_v4l2_debug;
195 @@ -66,6 +63,7 @@ struct bm2835_mmal_dev {
196                 unsigned int     height;  /* height */
197                 unsigned int     stride;  /* stride */
198                 struct mmal_fmt  *fmt;
199 +               struct v4l2_fract          timeperframe;
200  
201                 /* H264 encode bitrate */
202                 int         encode_bitrate;
203 --- a/drivers/media/platform/bcm2835/controls.c
204 +++ b/drivers/media/platform/bcm2835/controls.c
205 @@ -152,10 +152,7 @@ static int ctrl_set_rational(struct bm28
206                       struct v4l2_ctrl *ctrl,
207                       const struct bm2835_mmal_v4l2_ctrl *mmal_ctrl)
208  {
209 -       struct  {
210 -               s32 num;    /**< Numerator */
211 -               s32 den;    /**< Denominator */
212 -       } rational_value;
213 +       struct mmal_parameter_rational rational_value;
214         struct vchiq_mmal_port *control;
215  
216         control = &dev->component[MMAL_COMPONENT_CAMERA]->control;
217 --- a/drivers/media/platform/bcm2835/mmal-parameters.h
218 +++ b/drivers/media/platform/bcm2835/mmal-parameters.h
219 @@ -164,6 +164,11 @@ enum mmal_parameter_camera_type {
220         MMAL_PARAMETER_SHUTTER_SPEED              /**< Takes a @ref MMAL_PARAMETER_UINT32_T */
221  };
222  
223 +struct mmal_parameter_rational {
224 +       s32 num;    /**< Numerator */
225 +       s32 den;    /**< Denominator */
226 +};
227 +
228  enum mmal_parameter_camera_config_timestamp_mode {
229         MMAL_PARAM_TIMESTAMP_MODE_ZERO = 0, /* Always timestamp frames as 0 */
230         MMAL_PARAM_TIMESTAMP_MODE_RAW_STC,  /* Use the raw STC value