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