Merge commit 'v2.6.34.7' into dev-df3210-staging
[linux-2.6/parrot-frames.git] / drivers / staging / go7007 / go7007-v4l2.c
blob723c1a64d87f3007f5f7da252e160d7cd0453f66
1 /*
2 * Copyright (C) 2005-2006 Micronas USA Inc.
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.
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.
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.
18 #include <linux/module.h>
19 #include <linux/init.h>
20 #include <linux/version.h>
21 #include <linux/delay.h>
22 #include <linux/sched.h>
23 #include <linux/spinlock.h>
24 #include <linux/slab.h>
25 #include <linux/fs.h>
26 #include <linux/unistd.h>
27 #include <linux/time.h>
28 #include <linux/vmalloc.h>
29 #include <linux/pagemap.h>
30 #include <linux/videodev2.h>
31 #include <media/v4l2-common.h>
32 #include <media/v4l2-ioctl.h>
33 #include <media/v4l2-subdev.h>
34 #include <linux/i2c.h>
35 #include <linux/mutex.h>
36 #include <linux/uaccess.h>
37 #include <asm/system.h>
39 #include "go7007.h"
40 #include "go7007-priv.h"
41 #include "wis-i2c.h"
43 /* Temporary defines until accepted in v4l-dvb */
44 #ifndef V4L2_MPEG_STREAM_TYPE_MPEG_ELEM
45 #define V4L2_MPEG_STREAM_TYPE_MPEG_ELEM 6 /* MPEG elementary stream */
46 #endif
47 #ifndef V4L2_MPEG_VIDEO_ENCODING_MPEG_4
48 #define V4L2_MPEG_VIDEO_ENCODING_MPEG_4 3
49 #endif
51 #define call_all(dev, o, f, args...) \
52 v4l2_device_call_until_err(dev, 0, o, f, ##args)
54 static void deactivate_buffer(struct go7007_buffer *gobuf)
56 int i;
58 if (gobuf->state != BUF_STATE_IDLE) {
59 list_del(&gobuf->stream);
60 gobuf->state = BUF_STATE_IDLE;
62 if (gobuf->page_count > 0) {
63 for (i = 0; i < gobuf->page_count; ++i)
64 page_cache_release(gobuf->pages[i]);
65 gobuf->page_count = 0;
69 static void abort_queued(struct go7007 *go)
71 struct go7007_buffer *gobuf, *next;
73 list_for_each_entry_safe(gobuf, next, &go->stream, stream) {
74 deactivate_buffer(gobuf);
78 static int go7007_streamoff(struct go7007 *go)
80 int retval = -EINVAL;
81 unsigned long flags;
83 mutex_lock(&go->hw_lock);
84 if (go->streaming) {
85 go->streaming = 0;
86 go7007_stream_stop(go);
87 spin_lock_irqsave(&go->spinlock, flags);
88 abort_queued(go);
89 spin_unlock_irqrestore(&go->spinlock, flags);
90 go7007_reset_encoder(go);
91 retval = 0;
93 mutex_unlock(&go->hw_lock);
94 return 0;
97 static int go7007_open(struct file *file)
99 struct go7007 *go = video_get_drvdata(video_devdata(file));
100 struct go7007_file *gofh;
102 if (go->status != STATUS_ONLINE)
103 return -EBUSY;
104 gofh = kmalloc(sizeof(struct go7007_file), GFP_KERNEL);
105 if (gofh == NULL)
106 return -ENOMEM;
107 ++go->ref_count;
108 gofh->go = go;
109 mutex_init(&gofh->lock);
110 gofh->buf_count = 0;
111 file->private_data = gofh;
112 return 0;
115 static int go7007_release(struct file *file)
117 struct go7007_file *gofh = file->private_data;
118 struct go7007 *go = gofh->go;
120 if (gofh->buf_count > 0) {
121 go7007_streamoff(go);
122 go->in_use = 0;
123 kfree(gofh->bufs);
124 gofh->buf_count = 0;
126 kfree(gofh);
127 if (--go->ref_count == 0)
128 kfree(go);
129 file->private_data = NULL;
130 return 0;
133 static u32 get_frame_type_flag(struct go7007_buffer *gobuf, int format)
135 u8 *f = page_address(gobuf->pages[0]);
137 switch (format) {
138 case GO7007_FORMAT_MJPEG:
139 return V4L2_BUF_FLAG_KEYFRAME;
140 case GO7007_FORMAT_MPEG4:
141 switch ((f[gobuf->frame_offset + 4] >> 6) & 0x3) {
142 case 0:
143 return V4L2_BUF_FLAG_KEYFRAME;
144 case 1:
145 return V4L2_BUF_FLAG_PFRAME;
146 case 2:
147 return V4L2_BUF_FLAG_BFRAME;
148 default:
149 return 0;
151 case GO7007_FORMAT_MPEG1:
152 case GO7007_FORMAT_MPEG2:
153 switch ((f[gobuf->frame_offset + 5] >> 3) & 0x7) {
154 case 1:
155 return V4L2_BUF_FLAG_KEYFRAME;
156 case 2:
157 return V4L2_BUF_FLAG_PFRAME;
158 case 3:
159 return V4L2_BUF_FLAG_BFRAME;
160 default:
161 return 0;
165 return 0;
168 static int set_capture_size(struct go7007 *go, struct v4l2_format *fmt, int try)
170 int sensor_height = 0, sensor_width = 0;
171 int width, height, i;
173 if (fmt != NULL && fmt->fmt.pix.pixelformat != V4L2_PIX_FMT_MJPEG &&
174 fmt->fmt.pix.pixelformat != V4L2_PIX_FMT_MPEG &&
175 fmt->fmt.pix.pixelformat != V4L2_PIX_FMT_MPEG4)
176 return -EINVAL;
178 switch (go->standard) {
179 case GO7007_STD_NTSC:
180 sensor_width = 720;
181 sensor_height = 480;
182 break;
183 case GO7007_STD_PAL:
184 sensor_width = 720;
185 sensor_height = 576;
186 break;
187 case GO7007_STD_OTHER:
188 sensor_width = go->board_info->sensor_width;
189 sensor_height = go->board_info->sensor_height;
190 break;
193 if (fmt == NULL) {
194 width = sensor_width;
195 height = sensor_height;
196 } else if (go->board_info->sensor_flags & GO7007_SENSOR_SCALING) {
197 if (fmt->fmt.pix.width > sensor_width)
198 width = sensor_width;
199 else if (fmt->fmt.pix.width < 144)
200 width = 144;
201 else
202 width = fmt->fmt.pix.width & ~0x0f;
204 if (fmt->fmt.pix.height > sensor_height)
205 height = sensor_height;
206 else if (fmt->fmt.pix.height < 96)
207 height = 96;
208 else
209 height = fmt->fmt.pix.height & ~0x0f;
210 } else {
211 int requested_size = fmt->fmt.pix.width * fmt->fmt.pix.height;
212 int sensor_size = sensor_width * sensor_height;
214 if (64 * requested_size < 9 * sensor_size) {
215 width = sensor_width / 4;
216 height = sensor_height / 4;
217 } else if (64 * requested_size < 36 * sensor_size) {
218 width = sensor_width / 2;
219 height = sensor_height / 2;
220 } else {
221 width = sensor_width;
222 height = sensor_height;
224 width &= ~0xf;
225 height &= ~0xf;
228 if (fmt != NULL) {
229 u32 pixelformat = fmt->fmt.pix.pixelformat;
231 memset(fmt, 0, sizeof(*fmt));
232 fmt->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
233 fmt->fmt.pix.width = width;
234 fmt->fmt.pix.height = height;
235 fmt->fmt.pix.pixelformat = pixelformat;
236 fmt->fmt.pix.field = V4L2_FIELD_NONE;
237 fmt->fmt.pix.bytesperline = 0;
238 fmt->fmt.pix.sizeimage = GO7007_BUF_SIZE;
239 fmt->fmt.pix.colorspace = V4L2_COLORSPACE_SMPTE170M; /* ?? */
242 if (try)
243 return 0;
245 go->width = width;
246 go->height = height;
247 go->encoder_h_offset = go->board_info->sensor_h_offset;
248 go->encoder_v_offset = go->board_info->sensor_v_offset;
249 for (i = 0; i < 4; ++i)
250 go->modet[i].enable = 0;
251 for (i = 0; i < 1624; ++i)
252 go->modet_map[i] = 0;
254 if (go->board_info->sensor_flags & GO7007_SENSOR_SCALING) {
255 struct v4l2_format res;
257 if (fmt != NULL) {
258 res = *fmt;
259 } else {
260 res.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
261 res.fmt.pix.width = width;
264 if (height > sensor_height / 2) {
265 res.fmt.pix.height = height / 2;
266 go->encoder_v_halve = 0;
267 } else {
268 res.fmt.pix.height = height;
269 go->encoder_v_halve = 1;
271 call_all(&go->v4l2_dev, video, s_fmt, &res);
272 } else {
273 if (width <= sensor_width / 4) {
274 go->encoder_h_halve = 1;
275 go->encoder_v_halve = 1;
276 go->encoder_subsample = 1;
277 } else if (width <= sensor_width / 2) {
278 go->encoder_h_halve = 1;
279 go->encoder_v_halve = 1;
280 go->encoder_subsample = 0;
281 } else {
282 go->encoder_h_halve = 0;
283 go->encoder_v_halve = 0;
284 go->encoder_subsample = 0;
288 if (fmt == NULL)
289 return 0;
291 switch (fmt->fmt.pix.pixelformat) {
292 case V4L2_PIX_FMT_MPEG:
293 if (go->format == GO7007_FORMAT_MPEG1 ||
294 go->format == GO7007_FORMAT_MPEG2 ||
295 go->format == GO7007_FORMAT_MPEG4)
296 break;
297 go->format = GO7007_FORMAT_MPEG1;
298 go->pali = 0;
299 go->aspect_ratio = GO7007_RATIO_1_1;
300 go->gop_size = go->sensor_framerate / 1000;
301 go->ipb = 0;
302 go->closed_gop = 1;
303 go->repeat_seqhead = 1;
304 go->seq_header_enable = 1;
305 go->gop_header_enable = 1;
306 go->dvd_mode = 0;
307 break;
308 /* Backwards compatibility only! */
309 case V4L2_PIX_FMT_MPEG4:
310 if (go->format == GO7007_FORMAT_MPEG4)
311 break;
312 go->format = GO7007_FORMAT_MPEG4;
313 go->pali = 0xf5;
314 go->aspect_ratio = GO7007_RATIO_1_1;
315 go->gop_size = go->sensor_framerate / 1000;
316 go->ipb = 0;
317 go->closed_gop = 1;
318 go->repeat_seqhead = 1;
319 go->seq_header_enable = 1;
320 go->gop_header_enable = 1;
321 go->dvd_mode = 0;
322 break;
323 case V4L2_PIX_FMT_MJPEG:
324 go->format = GO7007_FORMAT_MJPEG;
325 go->pali = 0;
326 go->aspect_ratio = GO7007_RATIO_1_1;
327 go->gop_size = 0;
328 go->ipb = 0;
329 go->closed_gop = 0;
330 go->repeat_seqhead = 0;
331 go->seq_header_enable = 0;
332 go->gop_header_enable = 0;
333 go->dvd_mode = 0;
334 break;
336 return 0;
339 #if 0
340 static int clip_to_modet_map(struct go7007 *go, int region,
341 struct v4l2_clip *clip_list)
343 struct v4l2_clip clip, *clip_ptr;
344 int x, y, mbnum;
346 /* Check if coordinates are OK and if any macroblocks are already
347 * used by other regions (besides 0) */
348 clip_ptr = clip_list;
349 while (clip_ptr) {
350 if (copy_from_user(&clip, clip_ptr, sizeof(clip)))
351 return -EFAULT;
352 if (clip.c.left < 0 || (clip.c.left & 0xF) ||
353 clip.c.width <= 0 || (clip.c.width & 0xF))
354 return -EINVAL;
355 if (clip.c.left + clip.c.width > go->width)
356 return -EINVAL;
357 if (clip.c.top < 0 || (clip.c.top & 0xF) ||
358 clip.c.height <= 0 || (clip.c.height & 0xF))
359 return -EINVAL;
360 if (clip.c.top + clip.c.height > go->height)
361 return -EINVAL;
362 for (y = 0; y < clip.c.height; y += 16)
363 for (x = 0; x < clip.c.width; x += 16) {
364 mbnum = (go->width >> 4) *
365 ((clip.c.top + y) >> 4) +
366 ((clip.c.left + x) >> 4);
367 if (go->modet_map[mbnum] != 0 &&
368 go->modet_map[mbnum] != region)
369 return -EBUSY;
371 clip_ptr = clip.next;
374 /* Clear old region macroblocks */
375 for (mbnum = 0; mbnum < 1624; ++mbnum)
376 if (go->modet_map[mbnum] == region)
377 go->modet_map[mbnum] = 0;
379 /* Claim macroblocks in this list */
380 clip_ptr = clip_list;
381 while (clip_ptr) {
382 if (copy_from_user(&clip, clip_ptr, sizeof(clip)))
383 return -EFAULT;
384 for (y = 0; y < clip.c.height; y += 16)
385 for (x = 0; x < clip.c.width; x += 16) {
386 mbnum = (go->width >> 4) *
387 ((clip.c.top + y) >> 4) +
388 ((clip.c.left + x) >> 4);
389 go->modet_map[mbnum] = region;
391 clip_ptr = clip.next;
393 return 0;
395 #endif
397 static int mpeg_query_ctrl(struct v4l2_queryctrl *ctrl)
399 static const u32 mpeg_ctrls[] = {
400 V4L2_CID_MPEG_CLASS,
401 V4L2_CID_MPEG_STREAM_TYPE,
402 V4L2_CID_MPEG_VIDEO_ENCODING,
403 V4L2_CID_MPEG_VIDEO_ASPECT,
404 V4L2_CID_MPEG_VIDEO_GOP_SIZE,
405 V4L2_CID_MPEG_VIDEO_GOP_CLOSURE,
406 V4L2_CID_MPEG_VIDEO_BITRATE,
409 static const u32 *ctrl_classes[] = {
410 mpeg_ctrls,
411 NULL
414 ctrl->id = v4l2_ctrl_next(ctrl_classes, ctrl->id);
416 switch (ctrl->id) {
417 case V4L2_CID_MPEG_CLASS:
418 return v4l2_ctrl_query_fill(ctrl, 0, 0, 0, 0);
419 case V4L2_CID_MPEG_STREAM_TYPE:
420 return v4l2_ctrl_query_fill(ctrl,
421 V4L2_MPEG_STREAM_TYPE_MPEG2_DVD,
422 V4L2_MPEG_STREAM_TYPE_MPEG_ELEM, 1,
423 V4L2_MPEG_STREAM_TYPE_MPEG_ELEM);
424 case V4L2_CID_MPEG_VIDEO_ENCODING:
425 return v4l2_ctrl_query_fill(ctrl,
426 V4L2_MPEG_VIDEO_ENCODING_MPEG_1,
427 V4L2_MPEG_VIDEO_ENCODING_MPEG_4, 1,
428 V4L2_MPEG_VIDEO_ENCODING_MPEG_2);
429 case V4L2_CID_MPEG_VIDEO_ASPECT:
430 return v4l2_ctrl_query_fill(ctrl,
431 V4L2_MPEG_VIDEO_ASPECT_1x1,
432 V4L2_MPEG_VIDEO_ASPECT_16x9, 1,
433 V4L2_MPEG_VIDEO_ASPECT_1x1);
434 case V4L2_CID_MPEG_VIDEO_GOP_SIZE:
435 return v4l2_ctrl_query_fill(ctrl, 0, 34, 1, 15);
436 case V4L2_CID_MPEG_VIDEO_GOP_CLOSURE:
437 return v4l2_ctrl_query_fill(ctrl, 0, 1, 1, 0);
438 case V4L2_CID_MPEG_VIDEO_BITRATE:
439 return v4l2_ctrl_query_fill(ctrl,
440 64000,
441 10000000, 1,
442 1500000);
443 default:
444 return -EINVAL;
446 return 0;
449 static int mpeg_s_ctrl(struct v4l2_control *ctrl, struct go7007 *go)
451 /* pretty sure we can't change any of these while streaming */
452 if (go->streaming)
453 return -EBUSY;
455 switch (ctrl->id) {
456 case V4L2_CID_MPEG_STREAM_TYPE:
457 switch (ctrl->value) {
458 case V4L2_MPEG_STREAM_TYPE_MPEG2_DVD:
459 go->format = GO7007_FORMAT_MPEG2;
460 go->bitrate = 9800000;
461 go->gop_size = 15;
462 go->pali = 0x48;
463 go->closed_gop = 1;
464 go->repeat_seqhead = 0;
465 go->seq_header_enable = 1;
466 go->gop_header_enable = 1;
467 go->dvd_mode = 1;
468 break;
469 case V4L2_MPEG_STREAM_TYPE_MPEG_ELEM:
470 /* todo: */
471 break;
472 default:
473 return -EINVAL;
475 break;
476 case V4L2_CID_MPEG_VIDEO_ENCODING:
477 switch (ctrl->value) {
478 case V4L2_MPEG_VIDEO_ENCODING_MPEG_1:
479 go->format = GO7007_FORMAT_MPEG1;
480 go->pali = 0;
481 break;
482 case V4L2_MPEG_VIDEO_ENCODING_MPEG_2:
483 go->format = GO7007_FORMAT_MPEG2;
484 /*if (mpeg->pali >> 24 == 2)
485 go->pali = mpeg->pali & 0xff;
486 else*/
487 go->pali = 0x48;
488 break;
489 case V4L2_MPEG_VIDEO_ENCODING_MPEG_4:
490 go->format = GO7007_FORMAT_MPEG4;
491 /*if (mpeg->pali >> 24 == 4)
492 go->pali = mpeg->pali & 0xff;
493 else*/
494 go->pali = 0xf5;
495 break;
496 default:
497 return -EINVAL;
499 go->gop_header_enable =
500 /*mpeg->flags & GO7007_MPEG_OMIT_GOP_HEADER
501 ? 0 :*/ 1;
502 /*if (mpeg->flags & GO7007_MPEG_REPEAT_SEQHEADER)
503 go->repeat_seqhead = 1;
504 else*/
505 go->repeat_seqhead = 0;
506 go->dvd_mode = 0;
507 break;
508 case V4L2_CID_MPEG_VIDEO_ASPECT:
509 if (go->format == GO7007_FORMAT_MJPEG)
510 return -EINVAL;
511 switch (ctrl->value) {
512 case V4L2_MPEG_VIDEO_ASPECT_1x1:
513 go->aspect_ratio = GO7007_RATIO_1_1;
514 break;
515 case V4L2_MPEG_VIDEO_ASPECT_4x3:
516 go->aspect_ratio = GO7007_RATIO_4_3;
517 break;
518 case V4L2_MPEG_VIDEO_ASPECT_16x9:
519 go->aspect_ratio = GO7007_RATIO_16_9;
520 break;
521 case V4L2_MPEG_VIDEO_ASPECT_221x100:
522 default:
523 return -EINVAL;
525 break;
526 case V4L2_CID_MPEG_VIDEO_GOP_SIZE:
527 if (ctrl->value < 0 || ctrl->value > 34)
528 return -EINVAL;
529 go->gop_size = ctrl->value;
530 break;
531 case V4L2_CID_MPEG_VIDEO_GOP_CLOSURE:
532 if (ctrl->value != 0 && ctrl->value != 1)
533 return -EINVAL;
534 go->closed_gop = ctrl->value;
535 break;
536 case V4L2_CID_MPEG_VIDEO_BITRATE:
537 /* Upper bound is kind of arbitrary here */
538 if (ctrl->value < 64000 || ctrl->value > 10000000)
539 return -EINVAL;
540 go->bitrate = ctrl->value;
541 break;
542 default:
543 return -EINVAL;
545 return 0;
548 static int mpeg_g_ctrl(struct v4l2_control *ctrl, struct go7007 *go)
550 switch (ctrl->id) {
551 case V4L2_CID_MPEG_STREAM_TYPE:
552 if (go->dvd_mode)
553 ctrl->value = V4L2_MPEG_STREAM_TYPE_MPEG2_DVD;
554 else
555 ctrl->value = V4L2_MPEG_STREAM_TYPE_MPEG_ELEM;
556 break;
557 case V4L2_CID_MPEG_VIDEO_ENCODING:
558 switch (go->format) {
559 case GO7007_FORMAT_MPEG1:
560 ctrl->value = V4L2_MPEG_VIDEO_ENCODING_MPEG_1;
561 break;
562 case GO7007_FORMAT_MPEG2:
563 ctrl->value = V4L2_MPEG_VIDEO_ENCODING_MPEG_2;
564 break;
565 case GO7007_FORMAT_MPEG4:
566 ctrl->value = V4L2_MPEG_VIDEO_ENCODING_MPEG_4;
567 break;
568 default:
569 return -EINVAL;
571 break;
572 case V4L2_CID_MPEG_VIDEO_ASPECT:
573 switch (go->aspect_ratio) {
574 case GO7007_RATIO_1_1:
575 ctrl->value = V4L2_MPEG_VIDEO_ASPECT_1x1;
576 break;
577 case GO7007_RATIO_4_3:
578 ctrl->value = V4L2_MPEG_VIDEO_ASPECT_4x3;
579 break;
580 case GO7007_RATIO_16_9:
581 ctrl->value = V4L2_MPEG_VIDEO_ASPECT_16x9;
582 break;
583 default:
584 return -EINVAL;
586 break;
587 case V4L2_CID_MPEG_VIDEO_GOP_SIZE:
588 ctrl->value = go->gop_size;
589 break;
590 case V4L2_CID_MPEG_VIDEO_GOP_CLOSURE:
591 ctrl->value = go->closed_gop;
592 break;
593 case V4L2_CID_MPEG_VIDEO_BITRATE:
594 ctrl->value = go->bitrate;
595 break;
596 default:
597 return -EINVAL;
599 return 0;
602 static int vidioc_querycap(struct file *file, void *priv,
603 struct v4l2_capability *cap)
605 struct go7007 *go = ((struct go7007_file *) priv)->go;
607 strlcpy(cap->driver, "go7007", sizeof(cap->driver));
608 strlcpy(cap->card, go->name, sizeof(cap->card));
609 #if 0
610 strlcpy(cap->bus_info, dev_name(&dev->udev->dev), sizeof(cap->bus_info));
611 #endif
613 cap->version = KERNEL_VERSION(0, 9, 8);
615 cap->capabilities = V4L2_CAP_VIDEO_CAPTURE |
616 V4L2_CAP_STREAMING; /* | V4L2_CAP_AUDIO; */
618 if (go->board_info->flags & GO7007_BOARD_HAS_TUNER)
619 cap->capabilities |= V4L2_CAP_TUNER;
621 return 0;
624 static int vidioc_enum_fmt_vid_cap(struct file *file, void *priv,
625 struct v4l2_fmtdesc *fmt)
627 char *desc = NULL;
629 switch (fmt->index) {
630 case 0:
631 fmt->pixelformat = V4L2_PIX_FMT_MJPEG;
632 desc = "Motion-JPEG";
633 break;
634 case 1:
635 fmt->pixelformat = V4L2_PIX_FMT_MPEG;
636 desc = "MPEG1/MPEG2/MPEG4";
637 break;
638 default:
639 return -EINVAL;
641 fmt->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
642 fmt->flags = V4L2_FMT_FLAG_COMPRESSED;
644 strncpy(fmt->description, desc, sizeof(fmt->description));
646 return 0;
649 static int vidioc_g_fmt_vid_cap(struct file *file, void *priv,
650 struct v4l2_format *fmt)
652 struct go7007 *go = ((struct go7007_file *) priv)->go;
654 fmt->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
655 fmt->fmt.pix.width = go->width;
656 fmt->fmt.pix.height = go->height;
657 fmt->fmt.pix.pixelformat = (go->format == GO7007_FORMAT_MJPEG) ?
658 V4L2_PIX_FMT_MJPEG : V4L2_PIX_FMT_MPEG;
659 fmt->fmt.pix.field = V4L2_FIELD_NONE;
660 fmt->fmt.pix.bytesperline = 0;
661 fmt->fmt.pix.sizeimage = GO7007_BUF_SIZE;
662 fmt->fmt.pix.colorspace = V4L2_COLORSPACE_SMPTE170M;
664 return 0;
667 static int vidioc_try_fmt_vid_cap(struct file *file, void *priv,
668 struct v4l2_format *fmt)
670 struct go7007 *go = ((struct go7007_file *) priv)->go;
672 return set_capture_size(go, fmt, 1);
675 static int vidioc_s_fmt_vid_cap(struct file *file, void *priv,
676 struct v4l2_format *fmt)
678 struct go7007 *go = ((struct go7007_file *) priv)->go;
680 if (go->streaming)
681 return -EBUSY;
683 return set_capture_size(go, fmt, 0);
686 static int vidioc_reqbufs(struct file *file, void *priv,
687 struct v4l2_requestbuffers *req)
689 struct go7007_file *gofh = priv;
690 struct go7007 *go = gofh->go;
691 int retval = -EBUSY;
692 unsigned int count, i;
694 if (go->streaming)
695 return retval;
697 if (req->type != V4L2_BUF_TYPE_VIDEO_CAPTURE ||
698 req->memory != V4L2_MEMORY_MMAP)
699 return -EINVAL;
701 mutex_lock(&gofh->lock);
702 for (i = 0; i < gofh->buf_count; ++i)
703 if (gofh->bufs[i].mapped > 0)
704 goto unlock_and_return;
706 mutex_lock(&go->hw_lock);
707 if (go->in_use > 0 && gofh->buf_count == 0) {
708 mutex_unlock(&go->hw_lock);
709 goto unlock_and_return;
712 if (gofh->buf_count > 0)
713 kfree(gofh->bufs);
715 retval = -ENOMEM;
716 count = req->count;
717 if (count > 0) {
718 if (count < 2)
719 count = 2;
720 if (count > 32)
721 count = 32;
723 gofh->bufs = kmalloc(count * sizeof(struct go7007_buffer),
724 GFP_KERNEL);
726 if (!gofh->bufs) {
727 mutex_unlock(&go->hw_lock);
728 goto unlock_and_return;
731 memset(gofh->bufs, 0, count * sizeof(struct go7007_buffer));
733 for (i = 0; i < count; ++i) {
734 gofh->bufs[i].go = go;
735 gofh->bufs[i].index = i;
736 gofh->bufs[i].state = BUF_STATE_IDLE;
737 gofh->bufs[i].mapped = 0;
740 go->in_use = 1;
741 } else {
742 go->in_use = 0;
745 gofh->buf_count = count;
746 mutex_unlock(&go->hw_lock);
747 mutex_unlock(&gofh->lock);
749 memset(req, 0, sizeof(*req));
751 req->count = count;
752 req->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
753 req->memory = V4L2_MEMORY_MMAP;
755 return 0;
757 unlock_and_return:
758 mutex_unlock(&gofh->lock);
759 return retval;
762 static int vidioc_querybuf(struct file *file, void *priv,
763 struct v4l2_buffer *buf)
765 struct go7007_file *gofh = priv;
766 int retval = -EINVAL;
767 unsigned int index;
769 if (buf->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
770 return retval;
772 index = buf->index;
774 mutex_lock(&gofh->lock);
775 if (index >= gofh->buf_count)
776 goto unlock_and_return;
778 memset(buf, 0, sizeof(*buf));
779 buf->index = index;
780 buf->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
782 switch (gofh->bufs[index].state) {
783 case BUF_STATE_QUEUED:
784 buf->flags = V4L2_BUF_FLAG_QUEUED;
785 break;
786 case BUF_STATE_DONE:
787 buf->flags = V4L2_BUF_FLAG_DONE;
788 break;
789 default:
790 buf->flags = 0;
793 if (gofh->bufs[index].mapped)
794 buf->flags |= V4L2_BUF_FLAG_MAPPED;
795 buf->memory = V4L2_MEMORY_MMAP;
796 buf->m.offset = index * GO7007_BUF_SIZE;
797 buf->length = GO7007_BUF_SIZE;
798 mutex_unlock(&gofh->lock);
800 return 0;
802 unlock_and_return:
803 mutex_unlock(&gofh->lock);
804 return retval;
807 static int vidioc_qbuf(struct file *file, void *priv, struct v4l2_buffer *buf)
809 struct go7007_file *gofh = priv;
810 struct go7007 *go = gofh->go;
811 struct go7007_buffer *gobuf;
812 unsigned long flags;
813 int retval = -EINVAL;
814 int ret;
816 if (buf->type != V4L2_BUF_TYPE_VIDEO_CAPTURE ||
817 buf->memory != V4L2_MEMORY_MMAP)
818 return retval;
820 mutex_lock(&gofh->lock);
821 if (buf->index < 0 || buf->index >= gofh->buf_count)
822 goto unlock_and_return;
824 gobuf = &gofh->bufs[buf->index];
825 if (!gobuf->mapped)
826 goto unlock_and_return;
828 retval = -EBUSY;
829 if (gobuf->state != BUF_STATE_IDLE)
830 goto unlock_and_return;
832 /* offset will be 0 until we really support USERPTR streaming */
833 gobuf->offset = gobuf->user_addr & ~PAGE_MASK;
834 gobuf->bytesused = 0;
835 gobuf->frame_offset = 0;
836 gobuf->modet_active = 0;
837 if (gobuf->offset > 0)
838 gobuf->page_count = GO7007_BUF_PAGES + 1;
839 else
840 gobuf->page_count = GO7007_BUF_PAGES;
842 retval = -ENOMEM;
843 down_read(&current->mm->mmap_sem);
844 ret = get_user_pages(current, current->mm,
845 gobuf->user_addr & PAGE_MASK, gobuf->page_count,
846 1, 1, gobuf->pages, NULL);
847 up_read(&current->mm->mmap_sem);
849 if (ret != gobuf->page_count) {
850 int i;
851 for (i = 0; i < ret; ++i)
852 page_cache_release(gobuf->pages[i]);
853 gobuf->page_count = 0;
854 goto unlock_and_return;
857 gobuf->state = BUF_STATE_QUEUED;
858 spin_lock_irqsave(&go->spinlock, flags);
859 list_add_tail(&gobuf->stream, &go->stream);
860 spin_unlock_irqrestore(&go->spinlock, flags);
861 mutex_unlock(&gofh->lock);
863 return 0;
865 unlock_and_return:
866 mutex_unlock(&gofh->lock);
867 return retval;
871 static int vidioc_dqbuf(struct file *file, void *priv, struct v4l2_buffer *buf)
873 struct go7007_file *gofh = priv;
874 struct go7007 *go = gofh->go;
875 struct go7007_buffer *gobuf;
876 int retval = -EINVAL;
877 unsigned long flags;
878 u32 frame_type_flag;
879 DEFINE_WAIT(wait);
881 if (buf->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
882 return retval;
883 if (buf->memory != V4L2_MEMORY_MMAP)
884 return retval;
886 mutex_lock(&gofh->lock);
887 if (list_empty(&go->stream))
888 goto unlock_and_return;
889 gobuf = list_entry(go->stream.next,
890 struct go7007_buffer, stream);
892 retval = -EAGAIN;
893 if (gobuf->state != BUF_STATE_DONE &&
894 !(file->f_flags & O_NONBLOCK)) {
895 for (;;) {
896 prepare_to_wait(&go->frame_waitq, &wait,
897 TASK_INTERRUPTIBLE);
898 if (gobuf->state == BUF_STATE_DONE)
899 break;
900 if (signal_pending(current)) {
901 retval = -ERESTARTSYS;
902 break;
904 schedule();
906 finish_wait(&go->frame_waitq, &wait);
908 if (gobuf->state != BUF_STATE_DONE)
909 goto unlock_and_return;
911 spin_lock_irqsave(&go->spinlock, flags);
912 deactivate_buffer(gobuf);
913 spin_unlock_irqrestore(&go->spinlock, flags);
914 frame_type_flag = get_frame_type_flag(gobuf, go->format);
915 gobuf->state = BUF_STATE_IDLE;
917 memset(buf, 0, sizeof(*buf));
918 buf->index = gobuf->index;
919 buf->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
920 buf->bytesused = gobuf->bytesused;
921 buf->flags = V4L2_BUF_FLAG_MAPPED | frame_type_flag;
922 buf->field = V4L2_FIELD_NONE;
923 buf->timestamp = gobuf->timestamp;
924 buf->sequence = gobuf->seq;
925 buf->memory = V4L2_MEMORY_MMAP;
926 buf->m.offset = gobuf->index * GO7007_BUF_SIZE;
927 buf->length = GO7007_BUF_SIZE;
928 buf->reserved = gobuf->modet_active;
930 mutex_unlock(&gofh->lock);
931 return 0;
933 unlock_and_return:
934 mutex_unlock(&gofh->lock);
935 return retval;
938 static int vidioc_streamon(struct file *file, void *priv,
939 enum v4l2_buf_type type)
941 struct go7007_file *gofh = priv;
942 struct go7007 *go = gofh->go;
943 int retval = 0;
945 if (type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
946 return -EINVAL;
948 mutex_lock(&gofh->lock);
949 mutex_lock(&go->hw_lock);
951 if (!go->streaming) {
952 go->streaming = 1;
953 go->next_seq = 0;
954 go->active_buf = NULL;
955 if (go7007_start_encoder(go) < 0)
956 retval = -EIO;
957 else
958 retval = 0;
960 mutex_unlock(&go->hw_lock);
961 mutex_unlock(&gofh->lock);
963 return retval;
966 static int vidioc_streamoff(struct file *file, void *priv,
967 enum v4l2_buf_type type)
969 struct go7007_file *gofh = priv;
970 struct go7007 *go = gofh->go;
972 if (type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
973 return -EINVAL;
974 mutex_lock(&gofh->lock);
975 go7007_streamoff(go);
976 mutex_unlock(&gofh->lock);
978 return 0;
981 static int vidioc_queryctrl(struct file *file, void *priv,
982 struct v4l2_queryctrl *query)
984 struct go7007 *go = ((struct go7007_file *) priv)->go;
985 int id = query->id;
987 if (0 == call_all(&go->v4l2_dev, core, queryctrl, query))
988 return 0;
990 query->id = id;
991 return mpeg_query_ctrl(query);
994 static int vidioc_g_ctrl(struct file *file, void *priv,
995 struct v4l2_control *ctrl)
997 struct go7007 *go = ((struct go7007_file *) priv)->go;
999 if (0 == call_all(&go->v4l2_dev, core, g_ctrl, ctrl))
1000 return 0;
1002 return mpeg_g_ctrl(ctrl, go);
1005 static int vidioc_s_ctrl(struct file *file, void *priv,
1006 struct v4l2_control *ctrl)
1008 struct go7007 *go = ((struct go7007_file *) priv)->go;
1010 if (0 == call_all(&go->v4l2_dev, core, s_ctrl, ctrl))
1011 return 0;
1013 return mpeg_s_ctrl(ctrl, go);
1016 static int vidioc_g_parm(struct file *filp, void *priv,
1017 struct v4l2_streamparm *parm)
1019 struct go7007 *go = ((struct go7007_file *) priv)->go;
1020 struct v4l2_fract timeperframe = {
1021 .numerator = 1001 * go->fps_scale,
1022 .denominator = go->sensor_framerate,
1025 if (parm->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
1026 return -EINVAL;
1028 parm->parm.capture.capability |= V4L2_CAP_TIMEPERFRAME;
1029 parm->parm.capture.timeperframe = timeperframe;
1031 return 0;
1034 static int vidioc_s_parm(struct file *filp, void *priv,
1035 struct v4l2_streamparm *parm)
1037 struct go7007 *go = ((struct go7007_file *) priv)->go;
1038 unsigned int n, d;
1040 if (parm->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
1041 return -EINVAL;
1042 if (parm->parm.capture.capturemode != 0)
1043 return -EINVAL;
1045 n = go->sensor_framerate *
1046 parm->parm.capture.timeperframe.numerator;
1047 d = 1001 * parm->parm.capture.timeperframe.denominator;
1048 if (n != 0 && d != 0 && n > d)
1049 go->fps_scale = (n + d/2) / d;
1050 else
1051 go->fps_scale = 1;
1053 return 0;
1056 /* VIDIOC_ENUMSTD on go7007 were used for enumberating the supported fps and
1057 its resolution, when the device is not connected to TV.
1058 This were an API abuse, probably used by the lack of specific IOCTL's to
1059 enumberate it, by the time the driver were written.
1061 However, since kernel 2.6.19, two new ioctls (VIDIOC_ENUM_FRAMEINTERVALS
1062 and VIDIOC_ENUM_FRAMESIZES) were added for this purpose.
1064 The two functions bellow implements the newer ioctls
1066 static int vidioc_enum_framesizes(struct file *filp, void *priv,
1067 struct v4l2_frmsizeenum *fsize)
1069 struct go7007 *go = ((struct go7007_file *) priv)->go;
1071 /* Return -EINVAL, if it is a TV board */
1072 if ((go->board_info->flags & GO7007_BOARD_HAS_TUNER) ||
1073 (go->board_info->sensor_flags & GO7007_SENSOR_TV))
1074 return -EINVAL;
1076 if (fsize->index > 0)
1077 return -EINVAL;
1079 fsize->type = V4L2_FRMSIZE_TYPE_DISCRETE;
1080 fsize->discrete.width = go->board_info->sensor_width;
1081 fsize->discrete.height = go->board_info->sensor_height;
1083 return 0;
1086 static int vidioc_enum_frameintervals(struct file *filp, void *priv,
1087 struct v4l2_frmivalenum *fival)
1089 struct go7007 *go = ((struct go7007_file *) priv)->go;
1091 /* Return -EINVAL, if it is a TV board */
1092 if ((go->board_info->flags & GO7007_BOARD_HAS_TUNER) ||
1093 (go->board_info->sensor_flags & GO7007_SENSOR_TV))
1094 return -EINVAL;
1096 if (fival->index > 0)
1097 return -EINVAL;
1099 fival->type = V4L2_FRMIVAL_TYPE_DISCRETE;
1100 fival->discrete.numerator = 1001;
1101 fival->discrete.denominator = go->board_info->sensor_framerate;
1103 return 0;
1106 static int vidioc_g_std(struct file *file, void *priv, v4l2_std_id *std)
1108 struct go7007 *go = ((struct go7007_file *) priv)->go;
1110 switch (go->standard) {
1111 case GO7007_STD_NTSC:
1112 *std = V4L2_STD_NTSC;
1113 break;
1114 case GO7007_STD_PAL:
1115 *std = V4L2_STD_PAL;
1116 break;
1117 default:
1118 return -EINVAL;
1121 return 0;
1124 static int vidioc_s_std(struct file *file, void *priv, v4l2_std_id *std)
1126 struct go7007 *go = ((struct go7007_file *) priv)->go;
1128 if (go->streaming)
1129 return -EBUSY;
1131 if (!(go->board_info->sensor_flags & GO7007_SENSOR_TV) && *std != 0)
1132 return -EINVAL;
1134 if (*std == 0)
1135 return -EINVAL;
1137 if ((go->board_info->flags & GO7007_BOARD_HAS_TUNER) &&
1138 go->input == go->board_info->num_inputs - 1) {
1139 if (!go->i2c_adapter_online)
1140 return -EIO;
1141 if (call_all(&go->v4l2_dev, core, s_std, *std) < 0)
1142 return -EINVAL;
1145 if (*std & V4L2_STD_NTSC) {
1146 go->standard = GO7007_STD_NTSC;
1147 go->sensor_framerate = 30000;
1148 } else if (*std & V4L2_STD_PAL) {
1149 go->standard = GO7007_STD_PAL;
1150 go->sensor_framerate = 25025;
1151 } else if (*std & V4L2_STD_SECAM) {
1152 go->standard = GO7007_STD_PAL;
1153 go->sensor_framerate = 25025;
1154 } else
1155 return -EINVAL;
1157 call_all(&go->v4l2_dev, core, s_std, *std);
1158 set_capture_size(go, NULL, 0);
1160 return 0;
1163 static int vidioc_querystd(struct file *file, void *priv, v4l2_std_id *std)
1165 struct go7007 *go = ((struct go7007_file *) priv)->go;
1167 if ((go->board_info->flags & GO7007_BOARD_HAS_TUNER) &&
1168 go->input == go->board_info->num_inputs - 1) {
1169 if (!go->i2c_adapter_online)
1170 return -EIO;
1171 return call_all(&go->v4l2_dev, video, querystd, std);
1172 } else if (go->board_info->sensor_flags & GO7007_SENSOR_TV)
1173 *std = V4L2_STD_NTSC | V4L2_STD_PAL | V4L2_STD_SECAM;
1174 else
1175 *std = 0;
1177 return 0;
1180 static int vidioc_enum_input(struct file *file, void *priv,
1181 struct v4l2_input *inp)
1183 struct go7007 *go = ((struct go7007_file *) priv)->go;
1185 if (inp->index >= go->board_info->num_inputs)
1186 return -EINVAL;
1188 strncpy(inp->name, go->board_info->inputs[inp->index].name,
1189 sizeof(inp->name));
1191 /* If this board has a tuner, it will be the last input */
1192 if ((go->board_info->flags & GO7007_BOARD_HAS_TUNER) &&
1193 inp->index == go->board_info->num_inputs - 1)
1194 inp->type = V4L2_INPUT_TYPE_TUNER;
1195 else
1196 inp->type = V4L2_INPUT_TYPE_CAMERA;
1198 inp->audioset = 0;
1199 inp->tuner = 0;
1200 if (go->board_info->sensor_flags & GO7007_SENSOR_TV)
1201 inp->std = V4L2_STD_NTSC | V4L2_STD_PAL |
1202 V4L2_STD_SECAM;
1203 else
1204 inp->std = 0;
1206 return 0;
1210 static int vidioc_g_input(struct file *file, void *priv, unsigned int *input)
1212 struct go7007 *go = ((struct go7007_file *) priv)->go;
1214 *input = go->input;
1216 return 0;
1219 static int vidioc_s_input(struct file *file, void *priv, unsigned int input)
1221 struct go7007 *go = ((struct go7007_file *) priv)->go;
1223 if (input >= go->board_info->num_inputs)
1224 return -EINVAL;
1225 if (go->streaming)
1226 return -EBUSY;
1228 go->input = input;
1230 return call_all(&go->v4l2_dev, video, s_routing, input, 0, 0);
1233 static int vidioc_g_tuner(struct file *file, void *priv,
1234 struct v4l2_tuner *t)
1236 struct go7007 *go = ((struct go7007_file *) priv)->go;
1238 if (!(go->board_info->flags & GO7007_BOARD_HAS_TUNER))
1239 return -EINVAL;
1240 if (t->index != 0)
1241 return -EINVAL;
1242 if (!go->i2c_adapter_online)
1243 return -EIO;
1245 return call_all(&go->v4l2_dev, tuner, g_tuner, t);
1248 static int vidioc_s_tuner(struct file *file, void *priv,
1249 struct v4l2_tuner *t)
1251 struct go7007 *go = ((struct go7007_file *) priv)->go;
1253 if (!(go->board_info->flags & GO7007_BOARD_HAS_TUNER))
1254 return -EINVAL;
1255 if (t->index != 0)
1256 return -EINVAL;
1257 if (!go->i2c_adapter_online)
1258 return -EIO;
1260 switch (go->board_id) {
1261 case GO7007_BOARDID_PX_TV402U_NA:
1262 case GO7007_BOARDID_PX_TV402U_JP:
1263 /* No selectable options currently */
1264 if (t->audmode != V4L2_TUNER_MODE_STEREO)
1265 return -EINVAL;
1266 break;
1269 return call_all(&go->v4l2_dev, tuner, s_tuner, t);
1272 static int vidioc_g_frequency(struct file *file, void *priv,
1273 struct v4l2_frequency *f)
1275 struct go7007 *go = ((struct go7007_file *) priv)->go;
1277 if (!(go->board_info->flags & GO7007_BOARD_HAS_TUNER))
1278 return -EINVAL;
1279 if (!go->i2c_adapter_online)
1280 return -EIO;
1282 f->type = V4L2_TUNER_ANALOG_TV;
1284 return call_all(&go->v4l2_dev, tuner, g_frequency, f);
1287 static int vidioc_s_frequency(struct file *file, void *priv,
1288 struct v4l2_frequency *f)
1290 struct go7007 *go = ((struct go7007_file *) priv)->go;
1292 if (!(go->board_info->flags & GO7007_BOARD_HAS_TUNER))
1293 return -EINVAL;
1294 if (!go->i2c_adapter_online)
1295 return -EIO;
1297 return call_all(&go->v4l2_dev, tuner, s_frequency, f);
1300 static int vidioc_cropcap(struct file *file, void *priv,
1301 struct v4l2_cropcap *cropcap)
1303 struct go7007 *go = ((struct go7007_file *) priv)->go;
1305 if (cropcap->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
1306 return -EINVAL;
1308 /* These specify the raw input of the sensor */
1309 switch (go->standard) {
1310 case GO7007_STD_NTSC:
1311 cropcap->bounds.top = 0;
1312 cropcap->bounds.left = 0;
1313 cropcap->bounds.width = 720;
1314 cropcap->bounds.height = 480;
1315 cropcap->defrect.top = 0;
1316 cropcap->defrect.left = 0;
1317 cropcap->defrect.width = 720;
1318 cropcap->defrect.height = 480;
1319 break;
1320 case GO7007_STD_PAL:
1321 cropcap->bounds.top = 0;
1322 cropcap->bounds.left = 0;
1323 cropcap->bounds.width = 720;
1324 cropcap->bounds.height = 576;
1325 cropcap->defrect.top = 0;
1326 cropcap->defrect.left = 0;
1327 cropcap->defrect.width = 720;
1328 cropcap->defrect.height = 576;
1329 break;
1330 case GO7007_STD_OTHER:
1331 cropcap->bounds.top = 0;
1332 cropcap->bounds.left = 0;
1333 cropcap->bounds.width = go->board_info->sensor_width;
1334 cropcap->bounds.height = go->board_info->sensor_height;
1335 cropcap->defrect.top = 0;
1336 cropcap->defrect.left = 0;
1337 cropcap->defrect.width = go->board_info->sensor_width;
1338 cropcap->defrect.height = go->board_info->sensor_height;
1339 break;
1342 return 0;
1345 static int vidioc_g_crop(struct file *file, void *priv, struct v4l2_crop *crop)
1347 struct go7007 *go = ((struct go7007_file *) priv)->go;
1349 if (crop->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
1350 return -EINVAL;
1352 crop->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
1354 /* These specify the raw input of the sensor */
1355 switch (go->standard) {
1356 case GO7007_STD_NTSC:
1357 crop->c.top = 0;
1358 crop->c.left = 0;
1359 crop->c.width = 720;
1360 crop->c.height = 480;
1361 break;
1362 case GO7007_STD_PAL:
1363 crop->c.top = 0;
1364 crop->c.left = 0;
1365 crop->c.width = 720;
1366 crop->c.height = 576;
1367 break;
1368 case GO7007_STD_OTHER:
1369 crop->c.top = 0;
1370 crop->c.left = 0;
1371 crop->c.width = go->board_info->sensor_width;
1372 crop->c.height = go->board_info->sensor_height;
1373 break;
1376 return 0;
1379 /* FIXME: vidioc_s_crop is not really implemented!!!
1381 static int vidioc_s_crop(struct file *file, void *priv, struct v4l2_crop *crop)
1383 if (crop->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
1384 return -EINVAL;
1386 return 0;
1389 static int vidioc_g_jpegcomp(struct file *file, void *priv,
1390 struct v4l2_jpegcompression *params)
1392 memset(params, 0, sizeof(*params));
1393 params->quality = 50; /* ?? */
1394 params->jpeg_markers = V4L2_JPEG_MARKER_DHT |
1395 V4L2_JPEG_MARKER_DQT;
1397 return 0;
1400 static int vidioc_s_jpegcomp(struct file *file, void *priv,
1401 struct v4l2_jpegcompression *params)
1403 if (params->quality != 50 ||
1404 params->jpeg_markers != (V4L2_JPEG_MARKER_DHT |
1405 V4L2_JPEG_MARKER_DQT))
1406 return -EINVAL;
1408 return 0;
1411 /* FIXME:
1412 Those ioctls are private, and not needed, since several standard
1413 extended controls already provide streaming control.
1414 So, those ioctls should be converted into vidioc_g_ext_ctrls()
1415 and vidioc_s_ext_ctrls()
1418 #if 0
1419 /* Temporary ioctls for controlling compression characteristics */
1420 case GO7007IOC_S_BITRATE:
1422 int *bitrate = arg;
1424 if (go->streaming)
1425 return -EINVAL;
1426 /* Upper bound is kind of arbitrary here */
1427 if (*bitrate < 64000 || *bitrate > 10000000)
1428 return -EINVAL;
1429 go->bitrate = *bitrate;
1430 return 0;
1432 case GO7007IOC_G_BITRATE:
1434 int *bitrate = arg;
1436 *bitrate = go->bitrate;
1437 return 0;
1439 case GO7007IOC_S_COMP_PARAMS:
1441 struct go7007_comp_params *comp = arg;
1443 if (go->format == GO7007_FORMAT_MJPEG)
1444 return -EINVAL;
1445 if (comp->gop_size > 0)
1446 go->gop_size = comp->gop_size;
1447 else
1448 go->gop_size = go->sensor_framerate / 1000;
1449 if (go->gop_size != 15)
1450 go->dvd_mode = 0;
1451 /*go->ipb = comp->max_b_frames > 0;*/ /* completely untested */
1452 if (go->board_info->sensor_flags & GO7007_SENSOR_TV) {
1453 switch (comp->aspect_ratio) {
1454 case GO7007_ASPECT_RATIO_4_3_NTSC:
1455 case GO7007_ASPECT_RATIO_4_3_PAL:
1456 go->aspect_ratio = GO7007_RATIO_4_3;
1457 break;
1458 case GO7007_ASPECT_RATIO_16_9_NTSC:
1459 case GO7007_ASPECT_RATIO_16_9_PAL:
1460 go->aspect_ratio = GO7007_RATIO_16_9;
1461 break;
1462 default:
1463 go->aspect_ratio = GO7007_RATIO_1_1;
1464 break;
1467 if (comp->flags & GO7007_COMP_OMIT_SEQ_HEADER) {
1468 go->dvd_mode = 0;
1469 go->seq_header_enable = 0;
1470 } else {
1471 go->seq_header_enable = 1;
1473 /* fall-through */
1475 case GO7007IOC_G_COMP_PARAMS:
1477 struct go7007_comp_params *comp = arg;
1479 if (go->format == GO7007_FORMAT_MJPEG)
1480 return -EINVAL;
1481 memset(comp, 0, sizeof(*comp));
1482 comp->gop_size = go->gop_size;
1483 comp->max_b_frames = go->ipb ? 2 : 0;
1484 switch (go->aspect_ratio) {
1485 case GO7007_RATIO_4_3:
1486 if (go->standard == GO7007_STD_NTSC)
1487 comp->aspect_ratio =
1488 GO7007_ASPECT_RATIO_4_3_NTSC;
1489 else
1490 comp->aspect_ratio =
1491 GO7007_ASPECT_RATIO_4_3_PAL;
1492 break;
1493 case GO7007_RATIO_16_9:
1494 if (go->standard == GO7007_STD_NTSC)
1495 comp->aspect_ratio =
1496 GO7007_ASPECT_RATIO_16_9_NTSC;
1497 else
1498 comp->aspect_ratio =
1499 GO7007_ASPECT_RATIO_16_9_PAL;
1500 break;
1501 default:
1502 comp->aspect_ratio = GO7007_ASPECT_RATIO_1_1;
1503 break;
1505 if (go->closed_gop)
1506 comp->flags |= GO7007_COMP_CLOSED_GOP;
1507 if (!go->seq_header_enable)
1508 comp->flags |= GO7007_COMP_OMIT_SEQ_HEADER;
1509 return 0;
1511 case GO7007IOC_S_MPEG_PARAMS:
1513 struct go7007_mpeg_params *mpeg = arg;
1515 if (go->format != GO7007_FORMAT_MPEG1 &&
1516 go->format != GO7007_FORMAT_MPEG2 &&
1517 go->format != GO7007_FORMAT_MPEG4)
1518 return -EINVAL;
1520 if (mpeg->flags & GO7007_MPEG_FORCE_DVD_MODE) {
1521 go->format = GO7007_FORMAT_MPEG2;
1522 go->bitrate = 9800000;
1523 go->gop_size = 15;
1524 go->pali = 0x48;
1525 go->closed_gop = 1;
1526 go->repeat_seqhead = 0;
1527 go->seq_header_enable = 1;
1528 go->gop_header_enable = 1;
1529 go->dvd_mode = 1;
1530 } else {
1531 switch (mpeg->mpeg_video_standard) {
1532 case GO7007_MPEG_VIDEO_MPEG1:
1533 go->format = GO7007_FORMAT_MPEG1;
1534 go->pali = 0;
1535 break;
1536 case GO7007_MPEG_VIDEO_MPEG2:
1537 go->format = GO7007_FORMAT_MPEG2;
1538 if (mpeg->pali >> 24 == 2)
1539 go->pali = mpeg->pali & 0xff;
1540 else
1541 go->pali = 0x48;
1542 break;
1543 case GO7007_MPEG_VIDEO_MPEG4:
1544 go->format = GO7007_FORMAT_MPEG4;
1545 if (mpeg->pali >> 24 == 4)
1546 go->pali = mpeg->pali & 0xff;
1547 else
1548 go->pali = 0xf5;
1549 break;
1550 default:
1551 return -EINVAL;
1553 go->gop_header_enable =
1554 mpeg->flags & GO7007_MPEG_OMIT_GOP_HEADER
1555 ? 0 : 1;
1556 if (mpeg->flags & GO7007_MPEG_REPEAT_SEQHEADER)
1557 go->repeat_seqhead = 1;
1558 else
1559 go->repeat_seqhead = 0;
1560 go->dvd_mode = 0;
1562 /* fall-through */
1564 case GO7007IOC_G_MPEG_PARAMS:
1566 struct go7007_mpeg_params *mpeg = arg;
1568 memset(mpeg, 0, sizeof(*mpeg));
1569 switch (go->format) {
1570 case GO7007_FORMAT_MPEG1:
1571 mpeg->mpeg_video_standard = GO7007_MPEG_VIDEO_MPEG1;
1572 mpeg->pali = 0;
1573 break;
1574 case GO7007_FORMAT_MPEG2:
1575 mpeg->mpeg_video_standard = GO7007_MPEG_VIDEO_MPEG2;
1576 mpeg->pali = GO7007_MPEG_PROFILE(2, go->pali);
1577 break;
1578 case GO7007_FORMAT_MPEG4:
1579 mpeg->mpeg_video_standard = GO7007_MPEG_VIDEO_MPEG4;
1580 mpeg->pali = GO7007_MPEG_PROFILE(4, go->pali);
1581 break;
1582 default:
1583 return -EINVAL;
1585 if (!go->gop_header_enable)
1586 mpeg->flags |= GO7007_MPEG_OMIT_GOP_HEADER;
1587 if (go->repeat_seqhead)
1588 mpeg->flags |= GO7007_MPEG_REPEAT_SEQHEADER;
1589 if (go->dvd_mode)
1590 mpeg->flags |= GO7007_MPEG_FORCE_DVD_MODE;
1591 return 0;
1593 case GO7007IOC_S_MD_PARAMS:
1595 struct go7007_md_params *mdp = arg;
1597 if (mdp->region > 3)
1598 return -EINVAL;
1599 if (mdp->trigger > 0) {
1600 go->modet[mdp->region].pixel_threshold =
1601 mdp->pixel_threshold >> 1;
1602 go->modet[mdp->region].motion_threshold =
1603 mdp->motion_threshold >> 1;
1604 go->modet[mdp->region].mb_threshold =
1605 mdp->trigger >> 1;
1606 go->modet[mdp->region].enable = 1;
1607 } else
1608 go->modet[mdp->region].enable = 0;
1609 /* fall-through */
1611 case GO7007IOC_G_MD_PARAMS:
1613 struct go7007_md_params *mdp = arg;
1614 int region = mdp->region;
1616 if (mdp->region > 3)
1617 return -EINVAL;
1618 memset(mdp, 0, sizeof(struct go7007_md_params));
1619 mdp->region = region;
1620 if (!go->modet[region].enable)
1621 return 0;
1622 mdp->pixel_threshold =
1623 (go->modet[region].pixel_threshold << 1) + 1;
1624 mdp->motion_threshold =
1625 (go->modet[region].motion_threshold << 1) + 1;
1626 mdp->trigger =
1627 (go->modet[region].mb_threshold << 1) + 1;
1628 return 0;
1630 case GO7007IOC_S_MD_REGION:
1632 struct go7007_md_region *region = arg;
1634 if (region->region < 1 || region->region > 3)
1635 return -EINVAL;
1636 return clip_to_modet_map(go, region->region, region->clips);
1638 #endif
1640 static ssize_t go7007_read(struct file *file, char __user *data,
1641 size_t count, loff_t *ppos)
1643 return -EINVAL;
1646 static void go7007_vm_open(struct vm_area_struct *vma)
1648 struct go7007_buffer *gobuf = vma->vm_private_data;
1650 ++gobuf->mapped;
1653 static void go7007_vm_close(struct vm_area_struct *vma)
1655 struct go7007_buffer *gobuf = vma->vm_private_data;
1656 unsigned long flags;
1658 if (--gobuf->mapped == 0) {
1659 spin_lock_irqsave(&gobuf->go->spinlock, flags);
1660 deactivate_buffer(gobuf);
1661 spin_unlock_irqrestore(&gobuf->go->spinlock, flags);
1665 /* Copied from videobuf-dma-sg.c */
1666 static int go7007_vm_fault(struct vm_area_struct *vma, struct vm_fault *vmf)
1668 struct page *page;
1670 page = alloc_page(GFP_USER | __GFP_DMA32);
1671 if (!page)
1672 return VM_FAULT_OOM;
1673 clear_user_highpage(page, (unsigned long)vmf->virtual_address);
1674 vmf->page = page;
1675 return 0;
1678 static struct vm_operations_struct go7007_vm_ops = {
1679 .open = go7007_vm_open,
1680 .close = go7007_vm_close,
1681 .fault = go7007_vm_fault,
1684 static int go7007_mmap(struct file *file, struct vm_area_struct *vma)
1686 struct go7007_file *gofh = file->private_data;
1687 unsigned int index;
1689 if (gofh->go->status != STATUS_ONLINE)
1690 return -EIO;
1691 if (!(vma->vm_flags & VM_SHARED))
1692 return -EINVAL; /* only support VM_SHARED mapping */
1693 if (vma->vm_end - vma->vm_start != GO7007_BUF_SIZE)
1694 return -EINVAL; /* must map exactly one full buffer */
1695 mutex_lock(&gofh->lock);
1696 index = vma->vm_pgoff / GO7007_BUF_PAGES;
1697 if (index >= gofh->buf_count) {
1698 mutex_unlock(&gofh->lock);
1699 return -EINVAL; /* trying to map beyond requested buffers */
1701 if (index * GO7007_BUF_PAGES != vma->vm_pgoff) {
1702 mutex_unlock(&gofh->lock);
1703 return -EINVAL; /* offset is not aligned on buffer boundary */
1705 if (gofh->bufs[index].mapped > 0) {
1706 mutex_unlock(&gofh->lock);
1707 return -EBUSY;
1709 gofh->bufs[index].mapped = 1;
1710 gofh->bufs[index].user_addr = vma->vm_start;
1711 vma->vm_ops = &go7007_vm_ops;
1712 vma->vm_flags |= VM_DONTEXPAND;
1713 vma->vm_flags &= ~VM_IO;
1714 vma->vm_private_data = &gofh->bufs[index];
1715 mutex_unlock(&gofh->lock);
1716 return 0;
1719 static unsigned int go7007_poll(struct file *file, poll_table *wait)
1721 struct go7007_file *gofh = file->private_data;
1722 struct go7007_buffer *gobuf;
1724 if (list_empty(&gofh->go->stream))
1725 return POLLERR;
1726 gobuf = list_entry(gofh->go->stream.next, struct go7007_buffer, stream);
1727 poll_wait(file, &gofh->go->frame_waitq, wait);
1728 if (gobuf->state == BUF_STATE_DONE)
1729 return POLLIN | POLLRDNORM;
1730 return 0;
1733 static void go7007_vfl_release(struct video_device *vfd)
1735 struct go7007 *go = video_get_drvdata(vfd);
1737 video_device_release(vfd);
1738 if (--go->ref_count == 0)
1739 kfree(go);
1742 static struct v4l2_file_operations go7007_fops = {
1743 .owner = THIS_MODULE,
1744 .open = go7007_open,
1745 .release = go7007_release,
1746 .ioctl = video_ioctl2,
1747 .read = go7007_read,
1748 .mmap = go7007_mmap,
1749 .poll = go7007_poll,
1752 static const struct v4l2_ioctl_ops video_ioctl_ops = {
1753 .vidioc_querycap = vidioc_querycap,
1754 .vidioc_enum_fmt_vid_cap = vidioc_enum_fmt_vid_cap,
1755 .vidioc_g_fmt_vid_cap = vidioc_g_fmt_vid_cap,
1756 .vidioc_try_fmt_vid_cap = vidioc_try_fmt_vid_cap,
1757 .vidioc_s_fmt_vid_cap = vidioc_s_fmt_vid_cap,
1758 .vidioc_reqbufs = vidioc_reqbufs,
1759 .vidioc_querybuf = vidioc_querybuf,
1760 .vidioc_qbuf = vidioc_qbuf,
1761 .vidioc_dqbuf = vidioc_dqbuf,
1762 .vidioc_g_std = vidioc_g_std,
1763 .vidioc_s_std = vidioc_s_std,
1764 .vidioc_querystd = vidioc_querystd,
1765 .vidioc_enum_input = vidioc_enum_input,
1766 .vidioc_g_input = vidioc_g_input,
1767 .vidioc_s_input = vidioc_s_input,
1768 .vidioc_queryctrl = vidioc_queryctrl,
1769 .vidioc_g_ctrl = vidioc_g_ctrl,
1770 .vidioc_s_ctrl = vidioc_s_ctrl,
1771 .vidioc_streamon = vidioc_streamon,
1772 .vidioc_streamoff = vidioc_streamoff,
1773 .vidioc_g_tuner = vidioc_g_tuner,
1774 .vidioc_s_tuner = vidioc_s_tuner,
1775 .vidioc_g_frequency = vidioc_g_frequency,
1776 .vidioc_s_frequency = vidioc_s_frequency,
1777 .vidioc_g_parm = vidioc_g_parm,
1778 .vidioc_s_parm = vidioc_s_parm,
1779 .vidioc_enum_framesizes = vidioc_enum_framesizes,
1780 .vidioc_enum_frameintervals = vidioc_enum_frameintervals,
1781 .vidioc_cropcap = vidioc_cropcap,
1782 .vidioc_g_crop = vidioc_g_crop,
1783 .vidioc_s_crop = vidioc_s_crop,
1784 .vidioc_g_jpegcomp = vidioc_g_jpegcomp,
1785 .vidioc_s_jpegcomp = vidioc_s_jpegcomp,
1788 static struct video_device go7007_template = {
1789 .name = "go7007",
1790 .fops = &go7007_fops,
1791 .release = go7007_vfl_release,
1792 .ioctl_ops = &video_ioctl_ops,
1793 .tvnorms = V4L2_STD_ALL,
1794 .current_norm = V4L2_STD_NTSC,
1797 int go7007_v4l2_init(struct go7007 *go)
1799 int rv;
1801 go->video_dev = video_device_alloc();
1802 if (go->video_dev == NULL)
1803 return -ENOMEM;
1804 *go->video_dev = go7007_template;
1805 go->video_dev->parent = go->dev;
1806 rv = video_register_device(go->video_dev, VFL_TYPE_GRABBER, -1);
1807 if (rv < 0) {
1808 video_device_release(go->video_dev);
1809 go->video_dev = NULL;
1810 return rv;
1812 rv = v4l2_device_register(go->dev, &go->v4l2_dev);
1813 if (rv < 0) {
1814 video_device_release(go->video_dev);
1815 go->video_dev = NULL;
1816 return rv;
1818 video_set_drvdata(go->video_dev, go);
1819 ++go->ref_count;
1820 printk(KERN_INFO "%s: registered device %s [v4l2]\n",
1821 go->video_dev->name, video_device_node_name(go->video_dev));
1823 return 0;
1826 void go7007_v4l2_remove(struct go7007 *go)
1828 unsigned long flags;
1830 mutex_lock(&go->hw_lock);
1831 if (go->streaming) {
1832 go->streaming = 0;
1833 go7007_stream_stop(go);
1834 spin_lock_irqsave(&go->spinlock, flags);
1835 abort_queued(go);
1836 spin_unlock_irqrestore(&go->spinlock, flags);
1838 mutex_unlock(&go->hw_lock);
1839 if (go->video_dev)
1840 video_unregister_device(go->video_dev);
1841 v4l2_device_unregister(&go->v4l2_dev);