staging: delete non-required instances of include <linux/init.h>
[deliverable/linux.git] / drivers / staging / media / go7007 / go7007-v4l2.c
CommitLineData
866b8695
GKH
1/*
2 * Copyright (C) 2005-2006 Micronas USA Inc.
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License (Version 2) as
6 * published by the Free Software Foundation.
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 *
13 * You should have received a copy of the GNU General Public License
14 * along with this program; if not, write to the Free Software Foundation,
15 * Inc., 59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
16 */
17
18#include <linux/module.h>
866b8695
GKH
19#include <linux/delay.h>
20#include <linux/sched.h>
21#include <linux/spinlock.h>
5a0e3ad6 22#include <linux/slab.h>
866b8695
GKH
23#include <linux/fs.h>
24#include <linux/unistd.h>
25#include <linux/time.h>
26#include <linux/vmalloc.h>
27#include <linux/pagemap.h>
bae74320
HV
28#include <linux/i2c.h>
29#include <linux/mutex.h>
30#include <linux/uaccess.h>
df20d69e 31#include <linux/videodev2.h>
866b8695
GKH
32#include <media/v4l2-common.h>
33#include <media/v4l2-ioctl.h>
fa3c39bd 34#include <media/v4l2-subdev.h>
bae74320 35#include <media/v4l2-event.h>
ffcc1c08 36#include <media/videobuf2-vmalloc.h>
b95dd82c 37#include <media/saa7115.h>
866b8695
GKH
38
39#include "go7007.h"
40#include "go7007-priv.h"
866b8695 41
fa3c39bd
PE
42#define call_all(dev, o, f, args...) \
43 v4l2_device_call_until_err(dev, 0, o, f, ##args)
44
35d2d76d
HV
45static bool valid_pixelformat(u32 pixelformat)
46{
47 switch (pixelformat) {
48 case V4L2_PIX_FMT_MJPEG:
49 case V4L2_PIX_FMT_MPEG1:
50 case V4L2_PIX_FMT_MPEG2:
51 case V4L2_PIX_FMT_MPEG4:
52 return true;
53 default:
54 return false;
55 }
56}
57
ffcc1c08 58static u32 get_frame_type_flag(struct go7007_buffer *vb, int format)
866b8695 59{
ffcc1c08 60 u8 *ptr = vb2_plane_vaddr(&vb->vb, 0);
866b8695
GKH
61
62 switch (format) {
35d2d76d 63 case V4L2_PIX_FMT_MJPEG:
866b8695 64 return V4L2_BUF_FLAG_KEYFRAME;
35d2d76d 65 case V4L2_PIX_FMT_MPEG4:
ffcc1c08 66 switch ((ptr[vb->frame_offset + 4] >> 6) & 0x3) {
866b8695
GKH
67 case 0:
68 return V4L2_BUF_FLAG_KEYFRAME;
69 case 1:
70 return V4L2_BUF_FLAG_PFRAME;
71 case 2:
72 return V4L2_BUF_FLAG_BFRAME;
73 default:
74 return 0;
75 }
35d2d76d
HV
76 case V4L2_PIX_FMT_MPEG1:
77 case V4L2_PIX_FMT_MPEG2:
ffcc1c08 78 switch ((ptr[vb->frame_offset + 5] >> 3) & 0x7) {
866b8695
GKH
79 case 1:
80 return V4L2_BUF_FLAG_KEYFRAME;
81 case 2:
82 return V4L2_BUF_FLAG_PFRAME;
83 case 3:
84 return V4L2_BUF_FLAG_BFRAME;
85 default:
86 return 0;
87 }
88 }
89
90 return 0;
91}
92
50deb749 93static void get_resolution(struct go7007 *go, int *width, int *height)
866b8695 94{
866b8695
GKH
95 switch (go->standard) {
96 case GO7007_STD_NTSC:
50deb749
HV
97 *width = 720;
98 *height = 480;
866b8695
GKH
99 break;
100 case GO7007_STD_PAL:
50deb749
HV
101 *width = 720;
102 *height = 576;
866b8695
GKH
103 break;
104 case GO7007_STD_OTHER:
50deb749
HV
105 default:
106 *width = go->board_info->sensor_width;
107 *height = go->board_info->sensor_height;
866b8695
GKH
108 break;
109 }
50deb749
HV
110}
111
35d2d76d
HV
112static void set_formatting(struct go7007 *go)
113{
114 if (go->format == V4L2_PIX_FMT_MJPEG) {
115 go->pali = 0;
116 go->aspect_ratio = GO7007_RATIO_1_1;
117 go->gop_size = 0;
118 go->ipb = 0;
119 go->closed_gop = 0;
120 go->repeat_seqhead = 0;
121 go->seq_header_enable = 0;
122 go->gop_header_enable = 0;
123 go->dvd_mode = 0;
124 return;
125 }
126
127 switch (go->format) {
128 case V4L2_PIX_FMT_MPEG1:
129 go->pali = 0;
130 break;
131 default:
132 case V4L2_PIX_FMT_MPEG2:
133 go->pali = 0x48;
134 break;
135 case V4L2_PIX_FMT_MPEG4:
136 /* For future reference: this is the list of MPEG4
137 * profiles that are available, although they are
138 * untested:
139 *
140 * Profile pali
141 * -------------- ----
142 * PROFILE_S_L0 0x08
143 * PROFILE_S_L1 0x01
144 * PROFILE_S_L2 0x02
145 * PROFILE_S_L3 0x03
146 * PROFILE_ARTS_L1 0x91
147 * PROFILE_ARTS_L2 0x92
148 * PROFILE_ARTS_L3 0x93
149 * PROFILE_ARTS_L4 0x94
150 * PROFILE_AS_L0 0xf0
151 * PROFILE_AS_L1 0xf1
152 * PROFILE_AS_L2 0xf2
153 * PROFILE_AS_L3 0xf3
154 * PROFILE_AS_L4 0xf4
155 * PROFILE_AS_L5 0xf5
156 */
157 go->pali = 0xf5;
158 break;
159 }
160 go->gop_size = v4l2_ctrl_g_ctrl(go->mpeg_video_gop_size);
161 go->closed_gop = v4l2_ctrl_g_ctrl(go->mpeg_video_gop_closure);
7e4bfb9e 162 go->ipb = v4l2_ctrl_g_ctrl(go->mpeg_video_b_frames) != 0;
35d2d76d 163 go->bitrate = v4l2_ctrl_g_ctrl(go->mpeg_video_bitrate);
778ca511 164 go->repeat_seqhead = v4l2_ctrl_g_ctrl(go->mpeg_video_rep_seqheader);
35d2d76d
HV
165 go->gop_header_enable = 1;
166 go->dvd_mode = 0;
167 if (go->format == V4L2_PIX_FMT_MPEG2)
168 go->dvd_mode =
169 go->bitrate == 9800000 &&
170 go->gop_size == 15 &&
7e4bfb9e 171 go->ipb == 0 &&
778ca511 172 go->repeat_seqhead == 1 &&
35d2d76d 173 go->closed_gop;
35d2d76d
HV
174
175 switch (v4l2_ctrl_g_ctrl(go->mpeg_video_aspect_ratio)) {
176 default:
177 case V4L2_MPEG_VIDEO_ASPECT_1x1:
178 go->aspect_ratio = GO7007_RATIO_1_1;
179 break;
180 case V4L2_MPEG_VIDEO_ASPECT_4x3:
181 go->aspect_ratio = GO7007_RATIO_4_3;
182 break;
183 case V4L2_MPEG_VIDEO_ASPECT_16x9:
184 go->aspect_ratio = GO7007_RATIO_16_9;
185 break;
186 }
187}
188
50deb749
HV
189static int set_capture_size(struct go7007 *go, struct v4l2_format *fmt, int try)
190{
191 int sensor_height = 0, sensor_width = 0;
192 int width, height, i;
193
35d2d76d 194 if (fmt != NULL && !valid_pixelformat(fmt->fmt.pix.pixelformat))
50deb749
HV
195 return -EINVAL;
196
197 get_resolution(go, &sensor_width, &sensor_height);
866b8695
GKH
198
199 if (fmt == NULL) {
200 width = sensor_width;
201 height = sensor_height;
202 } else if (go->board_info->sensor_flags & GO7007_SENSOR_SCALING) {
203 if (fmt->fmt.pix.width > sensor_width)
204 width = sensor_width;
205 else if (fmt->fmt.pix.width < 144)
206 width = 144;
207 else
208 width = fmt->fmt.pix.width & ~0x0f;
209
210 if (fmt->fmt.pix.height > sensor_height)
211 height = sensor_height;
212 else if (fmt->fmt.pix.height < 96)
213 height = 96;
214 else
215 height = fmt->fmt.pix.height & ~0x0f;
216 } else {
50deb749 217 width = fmt->fmt.pix.width;
866b8695 218
50deb749 219 if (width <= sensor_width / 4) {
866b8695
GKH
220 width = sensor_width / 4;
221 height = sensor_height / 4;
50deb749 222 } else if (width <= sensor_width / 2) {
866b8695
GKH
223 width = sensor_width / 2;
224 height = sensor_height / 2;
225 } else {
226 width = sensor_width;
227 height = sensor_height;
228 }
229 width &= ~0xf;
230 height &= ~0xf;
231 }
232
233 if (fmt != NULL) {
234 u32 pixelformat = fmt->fmt.pix.pixelformat;
235
236 memset(fmt, 0, sizeof(*fmt));
237 fmt->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
238 fmt->fmt.pix.width = width;
239 fmt->fmt.pix.height = height;
240 fmt->fmt.pix.pixelformat = pixelformat;
241 fmt->fmt.pix.field = V4L2_FIELD_NONE;
242 fmt->fmt.pix.bytesperline = 0;
243 fmt->fmt.pix.sizeimage = GO7007_BUF_SIZE;
50deb749 244 fmt->fmt.pix.colorspace = V4L2_COLORSPACE_SMPTE170M;
866b8695
GKH
245 }
246
247 if (try)
248 return 0;
249
35d2d76d
HV
250 if (fmt)
251 go->format = fmt->fmt.pix.pixelformat;
866b8695
GKH
252 go->width = width;
253 go->height = height;
254 go->encoder_h_offset = go->board_info->sensor_h_offset;
255 go->encoder_v_offset = go->board_info->sensor_v_offset;
256 for (i = 0; i < 4; ++i)
257 go->modet[i].enable = 0;
258 for (i = 0; i < 1624; ++i)
259 go->modet_map[i] = 0;
260
261 if (go->board_info->sensor_flags & GO7007_SENSOR_SCALING) {
b8c75ed8 262 struct v4l2_mbus_framefmt mbus_fmt;
fa3c39bd 263
b8c75ed8 264 mbus_fmt.code = V4L2_MBUS_FMT_FIXED;
50deb749
HV
265 mbus_fmt.width = fmt ? fmt->fmt.pix.width : width;
266 mbus_fmt.height = height;
267 go->encoder_h_halve = 0;
268 go->encoder_v_halve = 0;
269 go->encoder_subsample = 0;
b8c75ed8 270 call_all(&go->v4l2_dev, video, s_mbus_fmt, &mbus_fmt);
866b8695
GKH
271 } else {
272 if (width <= sensor_width / 4) {
273 go->encoder_h_halve = 1;
274 go->encoder_v_halve = 1;
275 go->encoder_subsample = 1;
276 } else if (width <= sensor_width / 2) {
277 go->encoder_h_halve = 1;
278 go->encoder_v_halve = 1;
279 go->encoder_subsample = 0;
280 } else {
281 go->encoder_h_halve = 0;
282 go->encoder_v_halve = 0;
283 go->encoder_subsample = 0;
284 }
285 }
866b8695
GKH
286 return 0;
287}
288
8fca1cb3 289#if 0
866b8695
GKH
290static int clip_to_modet_map(struct go7007 *go, int region,
291 struct v4l2_clip *clip_list)
292{
293 struct v4l2_clip clip, *clip_ptr;
294 int x, y, mbnum;
295
296 /* Check if coordinates are OK and if any macroblocks are already
297 * used by other regions (besides 0) */
298 clip_ptr = clip_list;
299 while (clip_ptr) {
300 if (copy_from_user(&clip, clip_ptr, sizeof(clip)))
301 return -EFAULT;
302 if (clip.c.left < 0 || (clip.c.left & 0xF) ||
303 clip.c.width <= 0 || (clip.c.width & 0xF))
304 return -EINVAL;
305 if (clip.c.left + clip.c.width > go->width)
306 return -EINVAL;
307 if (clip.c.top < 0 || (clip.c.top & 0xF) ||
308 clip.c.height <= 0 || (clip.c.height & 0xF))
309 return -EINVAL;
310 if (clip.c.top + clip.c.height > go->height)
311 return -EINVAL;
312 for (y = 0; y < clip.c.height; y += 16)
313 for (x = 0; x < clip.c.width; x += 16) {
314 mbnum = (go->width >> 4) *
315 ((clip.c.top + y) >> 4) +
316 ((clip.c.left + x) >> 4);
317 if (go->modet_map[mbnum] != 0 &&
318 go->modet_map[mbnum] != region)
319 return -EBUSY;
320 }
321 clip_ptr = clip.next;
322 }
323
324 /* Clear old region macroblocks */
325 for (mbnum = 0; mbnum < 1624; ++mbnum)
326 if (go->modet_map[mbnum] == region)
327 go->modet_map[mbnum] = 0;
328
329 /* Claim macroblocks in this list */
330 clip_ptr = clip_list;
331 while (clip_ptr) {
332 if (copy_from_user(&clip, clip_ptr, sizeof(clip)))
333 return -EFAULT;
334 for (y = 0; y < clip.c.height; y += 16)
335 for (x = 0; x < clip.c.width; x += 16) {
336 mbnum = (go->width >> 4) *
337 ((clip.c.top + y) >> 4) +
338 ((clip.c.left + x) >> 4);
339 go->modet_map[mbnum] = region;
340 }
341 clip_ptr = clip.next;
342 }
343 return 0;
344}
669022a2 345#endif
866b8695 346
65f9f619
MCC
347static int vidioc_querycap(struct file *file, void *priv,
348 struct v4l2_capability *cap)
866b8695 349{
899eb84c 350 struct go7007 *go = video_drvdata(file);
866b8695 351
65f9f619
MCC
352 strlcpy(cap->driver, "go7007", sizeof(cap->driver));
353 strlcpy(cap->card, go->name, sizeof(cap->card));
4d217b83 354 strlcpy(cap->bus_info, go->bus_info, sizeof(cap->bus_info));
866b8695 355
ffcc1c08
HV
356 cap->device_caps = V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_READWRITE |
357 V4L2_CAP_STREAMING;
866b8695 358
5e410546
HV
359 if (go->board_info->num_aud_inputs)
360 cap->device_caps |= V4L2_CAP_AUDIO;
65f9f619 361 if (go->board_info->flags & GO7007_BOARD_HAS_TUNER)
4d217b83
HV
362 cap->device_caps |= V4L2_CAP_TUNER;
363 cap->capabilities = cap->device_caps | V4L2_CAP_DEVICE_CAPS;
65f9f619
MCC
364 return 0;
365}
866b8695 366
65f9f619
MCC
367static int vidioc_enum_fmt_vid_cap(struct file *file, void *priv,
368 struct v4l2_fmtdesc *fmt)
369{
370 char *desc = NULL;
d73f822c 371
65f9f619
MCC
372 switch (fmt->index) {
373 case 0:
374 fmt->pixelformat = V4L2_PIX_FMT_MJPEG;
35d2d76d 375 desc = "Motion JPEG";
65f9f619
MCC
376 break;
377 case 1:
35d2d76d
HV
378 fmt->pixelformat = V4L2_PIX_FMT_MPEG1;
379 desc = "MPEG-1 ES";
380 break;
381 case 2:
382 fmt->pixelformat = V4L2_PIX_FMT_MPEG2;
383 desc = "MPEG-2 ES";
384 break;
385 case 3:
386 fmt->pixelformat = V4L2_PIX_FMT_MPEG4;
387 desc = "MPEG-4 ES";
65f9f619
MCC
388 break;
389 default:
866b8695 390 return -EINVAL;
65f9f619
MCC
391 }
392 fmt->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
393 fmt->flags = V4L2_FMT_FLAG_COMPRESSED;
866b8695 394
65f9f619 395 strncpy(fmt->description, desc, sizeof(fmt->description));
866b8695 396
65f9f619
MCC
397 return 0;
398}
399
400static int vidioc_g_fmt_vid_cap(struct file *file, void *priv,
401 struct v4l2_format *fmt)
402{
899eb84c 403 struct go7007 *go = video_drvdata(file);
65f9f619
MCC
404
405 fmt->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
406 fmt->fmt.pix.width = go->width;
407 fmt->fmt.pix.height = go->height;
35d2d76d 408 fmt->fmt.pix.pixelformat = go->format;
65f9f619
MCC
409 fmt->fmt.pix.field = V4L2_FIELD_NONE;
410 fmt->fmt.pix.bytesperline = 0;
411 fmt->fmt.pix.sizeimage = GO7007_BUF_SIZE;
412 fmt->fmt.pix.colorspace = V4L2_COLORSPACE_SMPTE170M;
413
414 return 0;
415}
416
417static int vidioc_try_fmt_vid_cap(struct file *file, void *priv,
418 struct v4l2_format *fmt)
419{
899eb84c 420 struct go7007 *go = video_drvdata(file);
65f9f619
MCC
421
422 return set_capture_size(go, fmt, 1);
423}
424
425static int vidioc_s_fmt_vid_cap(struct file *file, void *priv,
426 struct v4l2_format *fmt)
427{
899eb84c 428 struct go7007 *go = video_drvdata(file);
65f9f619 429
ffcc1c08 430 if (vb2_is_busy(&go->vidq))
65f9f619
MCC
431 return -EBUSY;
432
433 return set_capture_size(go, fmt, 0);
434}
435
ffcc1c08
HV
436static int go7007_queue_setup(struct vb2_queue *q, const struct v4l2_format *fmt,
437 unsigned int *num_buffers, unsigned int *num_planes,
438 unsigned int sizes[], void *alloc_ctxs[])
65f9f619 439{
ffcc1c08
HV
440 sizes[0] = GO7007_BUF_SIZE;
441 *num_planes = 1;
866b8695 442
ffcc1c08
HV
443 if (*num_buffers < 2)
444 *num_buffers = 2;
65f9f619
MCC
445
446 return 0;
65f9f619
MCC
447}
448
ffcc1c08 449static void go7007_buf_queue(struct vb2_buffer *vb)
65f9f619 450{
ffcc1c08
HV
451 struct vb2_queue *vq = vb->vb2_queue;
452 struct go7007 *go = vb2_get_drv_priv(vq);
453 struct go7007_buffer *go7007_vb =
454 container_of(vb, struct go7007_buffer, vb);
65f9f619 455 unsigned long flags;
65f9f619 456
65f9f619 457 spin_lock_irqsave(&go->spinlock, flags);
ffcc1c08 458 list_add_tail(&go7007_vb->list, &go->vidq_active);
65f9f619 459 spin_unlock_irqrestore(&go->spinlock, flags);
ffcc1c08 460}
65f9f619 461
ffcc1c08
HV
462static int go7007_buf_prepare(struct vb2_buffer *vb)
463{
464 struct go7007_buffer *go7007_vb =
465 container_of(vb, struct go7007_buffer, vb);
65f9f619 466
ffcc1c08
HV
467 go7007_vb->modet_active = 0;
468 go7007_vb->frame_offset = 0;
469 vb->v4l2_planes[0].bytesused = 0;
470 return 0;
65f9f619
MCC
471}
472
ffcc1c08 473static int go7007_buf_finish(struct vb2_buffer *vb)
65f9f619 474{
ffcc1c08
HV
475 struct vb2_queue *vq = vb->vb2_queue;
476 struct go7007 *go = vb2_get_drv_priv(vq);
477 struct go7007_buffer *go7007_vb =
478 container_of(vb, struct go7007_buffer, vb);
479 u32 frame_type_flag = get_frame_type_flag(go7007_vb, go->format);
480 struct v4l2_buffer *buf = &vb->v4l2_buf;
481
482 buf->flags &= ~(V4L2_BUF_FLAG_KEYFRAME | V4L2_BUF_FLAG_BFRAME |
483 V4L2_BUF_FLAG_PFRAME);
484 buf->flags |= frame_type_flag;
65f9f619 485 buf->field = V4L2_FIELD_NONE;
65f9f619 486 return 0;
65f9f619
MCC
487}
488
ffcc1c08 489static int go7007_start_streaming(struct vb2_queue *q, unsigned int count)
65f9f619 490{
ffcc1c08
HV
491 struct go7007 *go = vb2_get_drv_priv(q);
492 int ret;
65f9f619 493
ffcc1c08 494 set_formatting(go);
fd9a40da 495 mutex_lock(&go->hw_lock);
ffcc1c08
HV
496 go->next_seq = 0;
497 go->active_buf = NULL;
498 q->streaming = 1;
499 if (go7007_start_encoder(go) < 0)
500 ret = -EIO;
501 else
502 ret = 0;
fd9a40da 503 mutex_unlock(&go->hw_lock);
ffcc1c08
HV
504 if (ret) {
505 q->streaming = 0;
506 return ret;
507 }
0a147c3b 508 call_all(&go->v4l2_dev, video, s_stream, 1);
35d2d76d
HV
509 v4l2_ctrl_grab(go->mpeg_video_gop_size, true);
510 v4l2_ctrl_grab(go->mpeg_video_gop_closure, true);
511 v4l2_ctrl_grab(go->mpeg_video_bitrate, true);
512 v4l2_ctrl_grab(go->mpeg_video_aspect_ratio, true);
1f1aed2e
HV
513 /* Turn on Capture LED */
514 if (go->board_id == GO7007_BOARDID_ADS_USBAV_709)
515 go7007_write_addr(go, 0x3c82, 0x0005);
ffcc1c08 516 return ret;
65f9f619
MCC
517}
518
ffcc1c08 519static int go7007_stop_streaming(struct vb2_queue *q)
65f9f619 520{
ffcc1c08
HV
521 struct go7007 *go = vb2_get_drv_priv(q);
522 unsigned long flags;
65f9f619 523
ffcc1c08
HV
524 q->streaming = 0;
525 go7007_stream_stop(go);
526 mutex_lock(&go->hw_lock);
527 go7007_reset_encoder(go);
528 mutex_unlock(&go->hw_lock);
0a147c3b 529 call_all(&go->v4l2_dev, video, s_stream, 0);
65f9f619 530
ffcc1c08
HV
531 spin_lock_irqsave(&go->spinlock, flags);
532 INIT_LIST_HEAD(&go->vidq_active);
533 spin_unlock_irqrestore(&go->spinlock, flags);
534 v4l2_ctrl_grab(go->mpeg_video_gop_size, false);
535 v4l2_ctrl_grab(go->mpeg_video_gop_closure, false);
536 v4l2_ctrl_grab(go->mpeg_video_bitrate, false);
537 v4l2_ctrl_grab(go->mpeg_video_aspect_ratio, false);
1f1aed2e
HV
538 /* Turn on Capture LED */
539 if (go->board_id == GO7007_BOARDID_ADS_USBAV_709)
540 go7007_write_addr(go, 0x3c82, 0x000d);
65f9f619
MCC
541 return 0;
542}
543
ffcc1c08
HV
544static struct vb2_ops go7007_video_qops = {
545 .queue_setup = go7007_queue_setup,
546 .buf_queue = go7007_buf_queue,
547 .buf_prepare = go7007_buf_prepare,
548 .buf_finish = go7007_buf_finish,
549 .start_streaming = go7007_start_streaming,
550 .stop_streaming = go7007_stop_streaming,
551 .wait_prepare = vb2_ops_wait_prepare,
552 .wait_finish = vb2_ops_wait_finish,
553};
554
65f9f619
MCC
555static int vidioc_g_parm(struct file *filp, void *priv,
556 struct v4l2_streamparm *parm)
557{
899eb84c 558 struct go7007 *go = video_drvdata(filp);
65f9f619
MCC
559 struct v4l2_fract timeperframe = {
560 .numerator = 1001 * go->fps_scale,
561 .denominator = go->sensor_framerate,
562 };
563
564 if (parm->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
565 return -EINVAL;
566
50deb749
HV
567 parm->parm.capture.readbuffers = 2;
568 parm->parm.capture.capability = V4L2_CAP_TIMEPERFRAME;
65f9f619
MCC
569 parm->parm.capture.timeperframe = timeperframe;
570
571 return 0;
572}
573
574static int vidioc_s_parm(struct file *filp, void *priv,
575 struct v4l2_streamparm *parm)
576{
899eb84c 577 struct go7007 *go = video_drvdata(filp);
65f9f619
MCC
578 unsigned int n, d;
579
580 if (parm->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
581 return -EINVAL;
65f9f619
MCC
582
583 n = go->sensor_framerate *
584 parm->parm.capture.timeperframe.numerator;
585 d = 1001 * parm->parm.capture.timeperframe.denominator;
586 if (n != 0 && d != 0 && n > d)
587 go->fps_scale = (n + d/2) / d;
588 else
589 go->fps_scale = 1;
590
50deb749 591 return vidioc_g_parm(filp, priv, parm);
65f9f619
MCC
592}
593
b47acf2a 594/* VIDIOC_ENUMSTD on go7007 were used for enumerating the supported fps and
65f9f619 595 its resolution, when the device is not connected to TV.
b47acf2a
JM
596 This is were an API abuse, probably used by the lack of specific IOCTL's to
597 enumerate it, by the time the driver was written.
65f9f619
MCC
598
599 However, since kernel 2.6.19, two new ioctls (VIDIOC_ENUM_FRAMEINTERVALS
600 and VIDIOC_ENUM_FRAMESIZES) were added for this purpose.
601
b47acf2a 602 The two functions below implement the newer ioctls
65f9f619 603*/
65f9f619
MCC
604static int vidioc_enum_framesizes(struct file *filp, void *priv,
605 struct v4l2_frmsizeenum *fsize)
606{
899eb84c 607 struct go7007 *go = video_drvdata(filp);
50deb749 608 int width, height;
65f9f619 609
50deb749 610 if (fsize->index > 2)
65f9f619
MCC
611 return -EINVAL;
612
35d2d76d 613 if (!valid_pixelformat(fsize->pixel_format))
65f9f619
MCC
614 return -EINVAL;
615
50deb749 616 get_resolution(go, &width, &height);
65f9f619 617 fsize->type = V4L2_FRMSIZE_TYPE_DISCRETE;
50deb749
HV
618 fsize->discrete.width = (width >> fsize->index) & ~0xf;
619 fsize->discrete.height = (height >> fsize->index) & ~0xf;
65f9f619
MCC
620 return 0;
621}
622
623static int vidioc_enum_frameintervals(struct file *filp, void *priv,
624 struct v4l2_frmivalenum *fival)
625{
899eb84c 626 struct go7007 *go = video_drvdata(filp);
50deb749
HV
627 int width, height;
628 int i;
65f9f619 629
50deb749 630 if (fival->index > 4)
65f9f619
MCC
631 return -EINVAL;
632
35d2d76d 633 if (!valid_pixelformat(fival->pixel_format))
65f9f619
MCC
634 return -EINVAL;
635
50deb749
HV
636 if (!(go->board_info->sensor_flags & GO7007_SENSOR_SCALING)) {
637 get_resolution(go, &width, &height);
638 for (i = 0; i <= 2; i++)
639 if (fival->width == ((width >> i) & ~0xf) &&
640 fival->height == ((height >> i) & ~0xf))
641 break;
642 if (i > 2)
643 return -EINVAL;
644 }
65f9f619 645 fival->type = V4L2_FRMIVAL_TYPE_DISCRETE;
50deb749
HV
646 fival->discrete.numerator = 1001 * (fival->index + 1);
647 fival->discrete.denominator = go->sensor_framerate;
65f9f619
MCC
648 return 0;
649}
650
bb871652
PE
651static int vidioc_g_std(struct file *file, void *priv, v4l2_std_id *std)
652{
899eb84c 653 struct go7007 *go = video_drvdata(file);
bb871652 654
50deb749
HV
655 *std = go->std;
656 return 0;
657}
658
659static int go7007_s_std(struct go7007 *go)
660{
3e4c8478 661 if (go->std & V4L2_STD_625_50) {
50deb749
HV
662 go->standard = GO7007_STD_PAL;
663 go->sensor_framerate = 25025;
3e4c8478
HV
664 } else {
665 go->standard = GO7007_STD_NTSC;
666 go->sensor_framerate = 30000;
bb871652
PE
667 }
668
50deb749
HV
669 call_all(&go->v4l2_dev, core, s_std, go->std);
670 set_capture_size(go, NULL, 0);
bb871652
PE
671 return 0;
672}
673
314527ac 674static int vidioc_s_std(struct file *file, void *priv, v4l2_std_id std)
65f9f619 675{
50deb749 676 struct go7007 *go = video_drvdata(file);
65f9f619 677
ffcc1c08 678 if (vb2_is_busy(&go->vidq))
65f9f619
MCC
679 return -EBUSY;
680
50deb749 681 go->std = std;
866b8695 682
50deb749 683 return go7007_s_std(go);
65f9f619 684}
d73f822c 685
bb871652
PE
686static int vidioc_querystd(struct file *file, void *priv, v4l2_std_id *std)
687{
899eb84c 688 struct go7007 *go = video_drvdata(file);
866b8695 689
50deb749 690 return call_all(&go->v4l2_dev, video, querystd, std);
bb871652 691}
866b8695 692
65f9f619
MCC
693static int vidioc_enum_input(struct file *file, void *priv,
694 struct v4l2_input *inp)
695{
899eb84c 696 struct go7007 *go = video_drvdata(file);
866b8695 697
65f9f619
MCC
698 if (inp->index >= go->board_info->num_inputs)
699 return -EINVAL;
866b8695 700
65f9f619
MCC
701 strncpy(inp->name, go->board_info->inputs[inp->index].name,
702 sizeof(inp->name));
866b8695 703
3acd16ab 704 /* If this board has a tuner, it will be the first input */
65f9f619 705 if ((go->board_info->flags & GO7007_BOARD_HAS_TUNER) &&
3acd16ab 706 inp->index == 0)
65f9f619
MCC
707 inp->type = V4L2_INPUT_TYPE_TUNER;
708 else
709 inp->type = V4L2_INPUT_TYPE_CAMERA;
866b8695 710
5e410546
HV
711 if (go->board_info->num_aud_inputs)
712 inp->audioset = (1 << go->board_info->num_aud_inputs) - 1;
713 else
714 inp->audioset = 0;
65f9f619
MCC
715 inp->tuner = 0;
716 if (go->board_info->sensor_flags & GO7007_SENSOR_TV)
50deb749 717 inp->std = video_devdata(file)->tvnorms;
65f9f619
MCC
718 else
719 inp->std = 0;
866b8695 720
65f9f619
MCC
721 return 0;
722}
866b8695 723
866b8695 724
65f9f619
MCC
725static int vidioc_g_input(struct file *file, void *priv, unsigned int *input)
726{
899eb84c 727 struct go7007 *go = video_drvdata(file);
866b8695 728
65f9f619 729 *input = go->input;
866b8695 730
65f9f619
MCC
731 return 0;
732}
733
5e410546
HV
734static int vidioc_enumaudio(struct file *file, void *fh, struct v4l2_audio *a)
735{
736 struct go7007 *go = video_drvdata(file);
737
738 if (a->index >= go->board_info->num_aud_inputs)
739 return -EINVAL;
740 strlcpy(a->name, go->board_info->aud_inputs[a->index].name, sizeof(a->name));
741 a->capability = V4L2_AUDCAP_STEREO;
742 return 0;
743}
744
745static int vidioc_g_audio(struct file *file, void *fh, struct v4l2_audio *a)
746{
747 struct go7007 *go = video_drvdata(file);
748
749 a->index = go->aud_input;
750 strlcpy(a->name, go->board_info->aud_inputs[go->aud_input].name, sizeof(a->name));
751 a->capability = V4L2_AUDCAP_STEREO;
752 return 0;
753}
754
755static int vidioc_s_audio(struct file *file, void *fh, const struct v4l2_audio *a)
756{
757 struct go7007 *go = video_drvdata(file);
758
759 if (a->index >= go->board_info->num_aud_inputs)
760 return -EINVAL;
761 go->aud_input = a->index;
762 v4l2_subdev_call(go->sd_audio, audio, s_routing,
763 go->board_info->aud_inputs[go->aud_input].audio_input, 0, 0);
764 return 0;
765}
766
50deb749 767static void go7007_s_input(struct go7007 *go)
65f9f619 768{
50deb749 769 unsigned int input = go->input;
866b8695 770
3acd16ab
HV
771 v4l2_subdev_call(go->sd_video, video, s_routing,
772 go->board_info->inputs[input].video_input, 0,
773 go->board_info->video_config);
774 if (go->board_info->num_aud_inputs) {
775 int aud_input = go->board_info->inputs[input].audio_index;
776
777 v4l2_subdev_call(go->sd_audio, audio, s_routing,
778 go->board_info->aud_inputs[aud_input].audio_input, 0, 0);
779 go->aud_input = aud_input;
780 }
50deb749
HV
781}
782
783static int vidioc_s_input(struct file *file, void *priv, unsigned int input)
784{
785 struct go7007 *go = video_drvdata(file);
786
787 if (input >= go->board_info->num_inputs)
788 return -EINVAL;
ffcc1c08 789 if (vb2_is_busy(&go->vidq))
50deb749
HV
790 return -EBUSY;
791
792 go->input = input;
793 go7007_s_input(go);
794
3acd16ab 795 return 0;
65f9f619
MCC
796}
797
798static int vidioc_g_tuner(struct file *file, void *priv,
799 struct v4l2_tuner *t)
800{
899eb84c 801 struct go7007 *go = video_drvdata(file);
65f9f619 802
65f9f619
MCC
803 if (t->index != 0)
804 return -EINVAL;
65f9f619 805
e4d2a616 806 strlcpy(t->name, "Tuner", sizeof(t->name));
fa3c39bd 807 return call_all(&go->v4l2_dev, tuner, g_tuner, t);
65f9f619
MCC
808}
809
810static int vidioc_s_tuner(struct file *file, void *priv,
2f73c7c5 811 const struct v4l2_tuner *t)
65f9f619 812{
899eb84c 813 struct go7007 *go = video_drvdata(file);
65f9f619 814
65f9f619
MCC
815 if (t->index != 0)
816 return -EINVAL;
65f9f619 817
fa3c39bd 818 return call_all(&go->v4l2_dev, tuner, s_tuner, t);
65f9f619
MCC
819}
820
821static int vidioc_g_frequency(struct file *file, void *priv,
822 struct v4l2_frequency *f)
823{
899eb84c 824 struct go7007 *go = video_drvdata(file);
65f9f619 825
50deb749 826 if (f->tuner)
65f9f619 827 return -EINVAL;
fa3c39bd
PE
828
829 return call_all(&go->v4l2_dev, tuner, g_frequency, f);
65f9f619
MCC
830}
831
832static int vidioc_s_frequency(struct file *file, void *priv,
b530a447 833 const struct v4l2_frequency *f)
65f9f619 834{
899eb84c 835 struct go7007 *go = video_drvdata(file);
65f9f619 836
50deb749 837 if (f->tuner)
65f9f619 838 return -EINVAL;
65f9f619 839
fa3c39bd 840 return call_all(&go->v4l2_dev, tuner, s_frequency, f);
65f9f619
MCC
841}
842
59d7b91a
HV
843static int vidioc_log_status(struct file *file, void *priv)
844{
899eb84c 845 struct go7007 *go = video_drvdata(file);
59d7b91a
HV
846
847 v4l2_ctrl_log_status(file, priv);
848 return call_all(&go->v4l2_dev, core, log_status);
849}
850
65f9f619
MCC
851/* FIXME:
852 Those ioctls are private, and not needed, since several standard
853 extended controls already provide streaming control.
854 So, those ioctls should be converted into vidioc_g_ext_ctrls()
855 and vidioc_s_ext_ctrls()
856 */
857
858#if 0
866b8695
GKH
859 case GO7007IOC_S_MD_PARAMS:
860 {
861 struct go7007_md_params *mdp = arg;
862
863 if (mdp->region > 3)
864 return -EINVAL;
865 if (mdp->trigger > 0) {
866 go->modet[mdp->region].pixel_threshold =
867 mdp->pixel_threshold >> 1;
868 go->modet[mdp->region].motion_threshold =
869 mdp->motion_threshold >> 1;
870 go->modet[mdp->region].mb_threshold =
871 mdp->trigger >> 1;
872 go->modet[mdp->region].enable = 1;
873 } else
874 go->modet[mdp->region].enable = 0;
875 /* fall-through */
876 }
866b8695
GKH
877 case GO7007IOC_S_MD_REGION:
878 {
879 struct go7007_md_region *region = arg;
880
881 if (region->region < 1 || region->region > 3)
882 return -EINVAL;
883 return clip_to_modet_map(go, region->region, region->clips);
884 }
65f9f619 885#endif
866b8695 886
60572c0d 887static struct v4l2_file_operations go7007_fops = {
866b8695 888 .owner = THIS_MODULE,
899eb84c 889 .open = v4l2_fh_open,
ffcc1c08
HV
890 .release = vb2_fop_release,
891 .unlocked_ioctl = video_ioctl2,
892 .read = vb2_fop_read,
893 .mmap = vb2_fop_mmap,
894 .poll = vb2_fop_poll,
866b8695
GKH
895};
896
65f9f619
MCC
897static const struct v4l2_ioctl_ops video_ioctl_ops = {
898 .vidioc_querycap = vidioc_querycap,
899 .vidioc_enum_fmt_vid_cap = vidioc_enum_fmt_vid_cap,
900 .vidioc_g_fmt_vid_cap = vidioc_g_fmt_vid_cap,
901 .vidioc_try_fmt_vid_cap = vidioc_try_fmt_vid_cap,
902 .vidioc_s_fmt_vid_cap = vidioc_s_fmt_vid_cap,
ffcc1c08
HV
903 .vidioc_reqbufs = vb2_ioctl_reqbufs,
904 .vidioc_querybuf = vb2_ioctl_querybuf,
905 .vidioc_qbuf = vb2_ioctl_qbuf,
906 .vidioc_dqbuf = vb2_ioctl_dqbuf,
bb871652 907 .vidioc_g_std = vidioc_g_std,
65f9f619 908 .vidioc_s_std = vidioc_s_std,
bb871652 909 .vidioc_querystd = vidioc_querystd,
65f9f619
MCC
910 .vidioc_enum_input = vidioc_enum_input,
911 .vidioc_g_input = vidioc_g_input,
912 .vidioc_s_input = vidioc_s_input,
5e410546
HV
913 .vidioc_enumaudio = vidioc_enumaudio,
914 .vidioc_g_audio = vidioc_g_audio,
915 .vidioc_s_audio = vidioc_s_audio,
ffcc1c08
HV
916 .vidioc_streamon = vb2_ioctl_streamon,
917 .vidioc_streamoff = vb2_ioctl_streamoff,
65f9f619
MCC
918 .vidioc_g_tuner = vidioc_g_tuner,
919 .vidioc_s_tuner = vidioc_s_tuner,
920 .vidioc_g_frequency = vidioc_g_frequency,
921 .vidioc_s_frequency = vidioc_s_frequency,
922 .vidioc_g_parm = vidioc_g_parm,
923 .vidioc_s_parm = vidioc_s_parm,
65f9f619
MCC
924 .vidioc_enum_framesizes = vidioc_enum_framesizes,
925 .vidioc_enum_frameintervals = vidioc_enum_frameintervals,
59d7b91a 926 .vidioc_log_status = vidioc_log_status,
bae74320
HV
927 .vidioc_subscribe_event = v4l2_ctrl_subscribe_event,
928 .vidioc_unsubscribe_event = v4l2_event_unsubscribe,
65f9f619
MCC
929};
930
866b8695
GKH
931static struct video_device go7007_template = {
932 .name = "go7007",
933 .fops = &go7007_fops,
6bb0e65d 934 .release = video_device_release_empty,
65f9f619
MCC
935 .ioctl_ops = &video_ioctl_ops,
936 .tvnorms = V4L2_STD_ALL,
866b8695
GKH
937};
938
9b8451d5
HV
939int go7007_v4l2_ctrl_init(struct go7007 *go)
940{
941 struct v4l2_ctrl_handler *hdl = &go->hdl;
942 struct v4l2_ctrl *ctrl;
943
7e4bfb9e 944 v4l2_ctrl_handler_init(hdl, 13);
35d2d76d 945 go->mpeg_video_gop_size = v4l2_ctrl_new_std(hdl, NULL,
9b8451d5 946 V4L2_CID_MPEG_VIDEO_GOP_SIZE, 0, 34, 1, 15);
35d2d76d
HV
947 go->mpeg_video_gop_closure = v4l2_ctrl_new_std(hdl, NULL,
948 V4L2_CID_MPEG_VIDEO_GOP_CLOSURE, 0, 1, 1, 1);
949 go->mpeg_video_bitrate = v4l2_ctrl_new_std(hdl, NULL,
9b8451d5 950 V4L2_CID_MPEG_VIDEO_BITRATE,
35d2d76d 951 64000, 10000000, 1, 9800000);
7e4bfb9e
VK
952 go->mpeg_video_b_frames = v4l2_ctrl_new_std(hdl, NULL,
953 V4L2_CID_MPEG_VIDEO_B_FRAMES, 0, 2, 2, 0);
778ca511
HV
954 go->mpeg_video_rep_seqheader = v4l2_ctrl_new_std(hdl, NULL,
955 V4L2_CID_MPEG_VIDEO_REPEAT_SEQ_HEADER, 0, 1, 1, 1);
7e4bfb9e 956
35d2d76d
HV
957 go->mpeg_video_aspect_ratio = v4l2_ctrl_new_std_menu(hdl, NULL,
958 V4L2_CID_MPEG_VIDEO_ASPECT,
959 V4L2_MPEG_VIDEO_ASPECT_16x9, 0,
960 V4L2_MPEG_VIDEO_ASPECT_1x1);
961 ctrl = v4l2_ctrl_new_std(hdl, NULL,
9b8451d5
HV
962 V4L2_CID_JPEG_ACTIVE_MARKER, 0,
963 V4L2_JPEG_ACTIVE_MARKER_DQT | V4L2_JPEG_ACTIVE_MARKER_DHT, 0,
964 V4L2_JPEG_ACTIVE_MARKER_DQT | V4L2_JPEG_ACTIVE_MARKER_DHT);
965 if (ctrl)
966 ctrl->flags |= V4L2_CTRL_FLAG_READ_ONLY;
967 if (hdl->error) {
968 int rv = hdl->error;
969
970 v4l2_err(&go->v4l2_dev, "Could not register controls\n");
971 return rv;
972 }
973 go->v4l2_dev.ctrl_handler = hdl;
974 return 0;
975}
976
866b8695
GKH
977int go7007_v4l2_init(struct go7007 *go)
978{
6bb0e65d 979 struct video_device *vdev = &go->vdev;
866b8695
GKH
980 int rv;
981
ffcc1c08
HV
982 mutex_init(&go->serialize_lock);
983 mutex_init(&go->queue_lock);
984
985 INIT_LIST_HEAD(&go->vidq_active);
986 go->vidq.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
987 go->vidq.io_modes = VB2_MMAP | VB2_USERPTR | VB2_READ;
988 go->vidq.ops = &go7007_video_qops;
989 go->vidq.mem_ops = &vb2_vmalloc_memops;
990 go->vidq.drv_priv = go;
991 go->vidq.buf_struct_size = sizeof(struct go7007_buffer);
992 go->vidq.timestamp_type = V4L2_BUF_FLAG_TIMESTAMP_MONOTONIC;
993 go->vidq.lock = &go->queue_lock;
994 rv = vb2_queue_init(&go->vidq);
995 if (rv)
996 return rv;
6bb0e65d
HV
997 *vdev = go7007_template;
998 vdev->lock = &go->serialize_lock;
999 vdev->queue = &go->vidq;
1000 set_bit(V4L2_FL_USE_FH_PRIO, &vdev->flags);
1001 video_set_drvdata(vdev, go);
1002 vdev->v4l2_dev = &go->v4l2_dev;
50deb749 1003 if (!v4l2_device_has_op(&go->v4l2_dev, video, querystd))
6bb0e65d 1004 v4l2_disable_ioctl(vdev, VIDIOC_QUERYSTD);
50deb749 1005 if (!(go->board_info->flags & GO7007_BOARD_HAS_TUNER)) {
6bb0e65d
HV
1006 v4l2_disable_ioctl(vdev, VIDIOC_S_FREQUENCY);
1007 v4l2_disable_ioctl(vdev, VIDIOC_G_FREQUENCY);
1008 v4l2_disable_ioctl(vdev, VIDIOC_S_TUNER);
1009 v4l2_disable_ioctl(vdev, VIDIOC_G_TUNER);
50deb749
HV
1010 } else {
1011 struct v4l2_frequency f = {
1012 .type = V4L2_TUNER_ANALOG_TV,
1013 .frequency = 980,
1014 };
1015
1016 call_all(&go->v4l2_dev, tuner, s_frequency, &f);
1017 }
1018 if (!(go->board_info->sensor_flags & GO7007_SENSOR_TV)) {
6bb0e65d
HV
1019 v4l2_disable_ioctl(vdev, VIDIOC_G_STD);
1020 v4l2_disable_ioctl(vdev, VIDIOC_S_STD);
1021 vdev->tvnorms = 0;
866b8695 1022 }
50deb749 1023 if (go->board_info->sensor_flags & GO7007_SENSOR_SCALING)
6bb0e65d 1024 v4l2_disable_ioctl(vdev, VIDIOC_ENUM_FRAMESIZES);
5e410546 1025 if (go->board_info->num_aud_inputs == 0) {
6bb0e65d
HV
1026 v4l2_disable_ioctl(vdev, VIDIOC_G_AUDIO);
1027 v4l2_disable_ioctl(vdev, VIDIOC_S_AUDIO);
1028 v4l2_disable_ioctl(vdev, VIDIOC_ENUMAUDIO);
5e410546 1029 }
b95dd82c
HV
1030 /* Setup correct crystal frequency on this board */
1031 if (go->board_info->sensor_flags & GO7007_SENSOR_SAA7115)
1032 v4l2_subdev_call(go->sd_video, video, s_crystal_freq,
1033 SAA7115_FREQ_24_576_MHZ,
1034 SAA7115_FREQ_FL_APLL | SAA7115_FREQ_FL_UCGC |
1035 SAA7115_FREQ_FL_DOUBLE_ASCLK);
50deb749
HV
1036 go7007_s_input(go);
1037 if (go->board_info->sensor_flags & GO7007_SENSOR_TV)
1038 go7007_s_std(go);
6bb0e65d
HV
1039 rv = video_register_device(vdev, VFL_TYPE_GRABBER, -1);
1040 if (rv < 0)
50deb749 1041 return rv;
34047bac 1042 dev_info(go->dev, "registered device %s [v4l2]\n",
6bb0e65d 1043 video_device_node_name(vdev));
866b8695
GKH
1044
1045 return 0;
1046}
1047
1048void go7007_v4l2_remove(struct go7007 *go)
1049{
9b8451d5 1050 v4l2_ctrl_handler_free(&go->hdl);
866b8695 1051}
This page took 0.80236 seconds and 5 git commands to generate.