perf record: Add missing -C option support for specifying profile cpu
[linux-2.6/mini2440.git] / drivers / staging / go7007 / go7007-v4l2.c
blob06cacd37bbd801a014f35fb45614177441cafab8
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/fs.h>
25 #include <linux/unistd.h>
26 #include <linux/time.h>
27 #include <linux/vmalloc.h>
28 #include <linux/pagemap.h>
29 #include <linux/videodev2.h>
30 #include <media/v4l2-common.h>
31 #include <media/v4l2-ioctl.h>
32 #include <linux/i2c.h>
33 #include <linux/semaphore.h>
34 #include <linux/uaccess.h>
35 #include <asm/system.h>
37 #include "go7007.h"
38 #include "go7007-priv.h"
39 #include "wis-i2c.h"
41 /* Temporary defines until accepted in v4l-dvb */
42 #ifndef V4L2_MPEG_STREAM_TYPE_MPEG_ELEM
43 #define V4L2_MPEG_STREAM_TYPE_MPEG_ELEM 6 /* MPEG elementary stream */
44 #endif
45 #ifndef V4L2_MPEG_VIDEO_ENCODING_MPEG_4
46 #define V4L2_MPEG_VIDEO_ENCODING_MPEG_4 3
47 #endif
49 static void deactivate_buffer(struct go7007_buffer *gobuf)
51 int i;
53 if (gobuf->state != BUF_STATE_IDLE) {
54 list_del(&gobuf->stream);
55 gobuf->state = BUF_STATE_IDLE;
57 if (gobuf->page_count > 0) {
58 for (i = 0; i < gobuf->page_count; ++i)
59 page_cache_release(gobuf->pages[i]);
60 gobuf->page_count = 0;
64 static void abort_queued(struct go7007 *go)
66 struct go7007_buffer *gobuf, *next;
68 list_for_each_entry_safe(gobuf, next, &go->stream, stream) {
69 deactivate_buffer(gobuf);
73 static int go7007_streamoff(struct go7007 *go)
75 int retval = -EINVAL;
76 unsigned long flags;
78 down(&go->hw_lock);
79 if (go->streaming) {
80 go->streaming = 0;
81 go7007_stream_stop(go);
82 spin_lock_irqsave(&go->spinlock, flags);
83 abort_queued(go);
84 spin_unlock_irqrestore(&go->spinlock, flags);
85 go7007_reset_encoder(go);
86 retval = 0;
88 up(&go->hw_lock);
89 return 0;
92 static int go7007_open(struct file *file)
94 struct go7007 *go = video_get_drvdata(video_devdata(file));
95 struct go7007_file *gofh;
97 if (go->status != STATUS_ONLINE)
98 return -EBUSY;
99 gofh = kmalloc(sizeof(struct go7007_file), GFP_KERNEL);
100 if (gofh == NULL)
101 return -ENOMEM;
102 ++go->ref_count;
103 gofh->go = go;
104 init_MUTEX(&gofh->lock);
105 gofh->buf_count = 0;
106 file->private_data = gofh;
107 return 0;
110 static int go7007_release(struct file *file)
112 struct go7007_file *gofh = file->private_data;
113 struct go7007 *go = gofh->go;
115 if (gofh->buf_count > 0) {
116 go7007_streamoff(go);
117 go->in_use = 0;
118 kfree(gofh->bufs);
119 gofh->buf_count = 0;
121 kfree(gofh);
122 if (--go->ref_count == 0)
123 kfree(go);
124 file->private_data = NULL;
125 return 0;
128 static u32 get_frame_type_flag(struct go7007_buffer *gobuf, int format)
130 u8 *f = page_address(gobuf->pages[0]);
132 switch (format) {
133 case GO7007_FORMAT_MJPEG:
134 return V4L2_BUF_FLAG_KEYFRAME;
135 case GO7007_FORMAT_MPEG4:
136 switch ((f[gobuf->frame_offset + 4] >> 6) & 0x3) {
137 case 0:
138 return V4L2_BUF_FLAG_KEYFRAME;
139 case 1:
140 return V4L2_BUF_FLAG_PFRAME;
141 case 2:
142 return V4L2_BUF_FLAG_BFRAME;
143 default:
144 return 0;
146 case GO7007_FORMAT_MPEG1:
147 case GO7007_FORMAT_MPEG2:
148 switch ((f[gobuf->frame_offset + 5] >> 3) & 0x7) {
149 case 1:
150 return V4L2_BUF_FLAG_KEYFRAME;
151 case 2:
152 return V4L2_BUF_FLAG_PFRAME;
153 case 3:
154 return V4L2_BUF_FLAG_BFRAME;
155 default:
156 return 0;
160 return 0;
163 static int set_capture_size(struct go7007 *go, struct v4l2_format *fmt, int try)
165 int sensor_height = 0, sensor_width = 0;
166 int width, height, i;
168 if (fmt != NULL && fmt->fmt.pix.pixelformat != V4L2_PIX_FMT_MJPEG &&
169 fmt->fmt.pix.pixelformat != V4L2_PIX_FMT_MPEG &&
170 fmt->fmt.pix.pixelformat != V4L2_PIX_FMT_MPEG4)
171 return -EINVAL;
173 switch (go->standard) {
174 case GO7007_STD_NTSC:
175 sensor_width = 720;
176 sensor_height = 480;
177 break;
178 case GO7007_STD_PAL:
179 sensor_width = 720;
180 sensor_height = 576;
181 break;
182 case GO7007_STD_OTHER:
183 sensor_width = go->board_info->sensor_width;
184 sensor_height = go->board_info->sensor_height;
185 break;
188 if (fmt == NULL) {
189 width = sensor_width;
190 height = sensor_height;
191 } else if (go->board_info->sensor_flags & GO7007_SENSOR_SCALING) {
192 if (fmt->fmt.pix.width > sensor_width)
193 width = sensor_width;
194 else if (fmt->fmt.pix.width < 144)
195 width = 144;
196 else
197 width = fmt->fmt.pix.width & ~0x0f;
199 if (fmt->fmt.pix.height > sensor_height)
200 height = sensor_height;
201 else if (fmt->fmt.pix.height < 96)
202 height = 96;
203 else
204 height = fmt->fmt.pix.height & ~0x0f;
205 } else {
206 int requested_size = fmt->fmt.pix.width * fmt->fmt.pix.height;
207 int sensor_size = sensor_width * sensor_height;
209 if (64 * requested_size < 9 * sensor_size) {
210 width = sensor_width / 4;
211 height = sensor_height / 4;
212 } else if (64 * requested_size < 36 * sensor_size) {
213 width = sensor_width / 2;
214 height = sensor_height / 2;
215 } else {
216 width = sensor_width;
217 height = sensor_height;
219 width &= ~0xf;
220 height &= ~0xf;
223 if (fmt != NULL) {
224 u32 pixelformat = fmt->fmt.pix.pixelformat;
226 memset(fmt, 0, sizeof(*fmt));
227 fmt->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
228 fmt->fmt.pix.width = width;
229 fmt->fmt.pix.height = height;
230 fmt->fmt.pix.pixelformat = pixelformat;
231 fmt->fmt.pix.field = V4L2_FIELD_NONE;
232 fmt->fmt.pix.bytesperline = 0;
233 fmt->fmt.pix.sizeimage = GO7007_BUF_SIZE;
234 fmt->fmt.pix.colorspace = V4L2_COLORSPACE_SMPTE170M; /* ?? */
237 if (try)
238 return 0;
240 go->width = width;
241 go->height = height;
242 go->encoder_h_offset = go->board_info->sensor_h_offset;
243 go->encoder_v_offset = go->board_info->sensor_v_offset;
244 for (i = 0; i < 4; ++i)
245 go->modet[i].enable = 0;
246 for (i = 0; i < 1624; ++i)
247 go->modet_map[i] = 0;
249 if (go->board_info->sensor_flags & GO7007_SENSOR_SCALING) {
250 struct video_decoder_resolution res;
252 res.width = width;
253 if (height > sensor_height / 2) {
254 res.height = height / 2;
255 go->encoder_v_halve = 0;
256 } else {
257 res.height = height;
258 go->encoder_v_halve = 1;
260 if (go->i2c_adapter_online)
261 i2c_clients_command(&go->i2c_adapter,
262 DECODER_SET_RESOLUTION, &res);
263 } else {
264 if (width <= sensor_width / 4) {
265 go->encoder_h_halve = 1;
266 go->encoder_v_halve = 1;
267 go->encoder_subsample = 1;
268 } else if (width <= sensor_width / 2) {
269 go->encoder_h_halve = 1;
270 go->encoder_v_halve = 1;
271 go->encoder_subsample = 0;
272 } else {
273 go->encoder_h_halve = 0;
274 go->encoder_v_halve = 0;
275 go->encoder_subsample = 0;
279 if (fmt == NULL)
280 return 0;
282 switch (fmt->fmt.pix.pixelformat) {
283 case V4L2_PIX_FMT_MPEG:
284 if (go->format == GO7007_FORMAT_MPEG1 ||
285 go->format == GO7007_FORMAT_MPEG2 ||
286 go->format == GO7007_FORMAT_MPEG4)
287 break;
288 go->format = GO7007_FORMAT_MPEG1;
289 go->pali = 0;
290 go->aspect_ratio = GO7007_RATIO_1_1;
291 go->gop_size = go->sensor_framerate / 1000;
292 go->ipb = 0;
293 go->closed_gop = 1;
294 go->repeat_seqhead = 1;
295 go->seq_header_enable = 1;
296 go->gop_header_enable = 1;
297 go->dvd_mode = 0;
298 break;
299 /* Backwards compatibility only! */
300 case V4L2_PIX_FMT_MPEG4:
301 if (go->format == GO7007_FORMAT_MPEG4)
302 break;
303 go->format = GO7007_FORMAT_MPEG4;
304 go->pali = 0xf5;
305 go->aspect_ratio = GO7007_RATIO_1_1;
306 go->gop_size = go->sensor_framerate / 1000;
307 go->ipb = 0;
308 go->closed_gop = 1;
309 go->repeat_seqhead = 1;
310 go->seq_header_enable = 1;
311 go->gop_header_enable = 1;
312 go->dvd_mode = 0;
313 break;
314 case V4L2_PIX_FMT_MJPEG:
315 go->format = GO7007_FORMAT_MJPEG;
316 go->pali = 0;
317 go->aspect_ratio = GO7007_RATIO_1_1;
318 go->gop_size = 0;
319 go->ipb = 0;
320 go->closed_gop = 0;
321 go->repeat_seqhead = 0;
322 go->seq_header_enable = 0;
323 go->gop_header_enable = 0;
324 go->dvd_mode = 0;
325 break;
327 return 0;
330 #if 0
331 static int clip_to_modet_map(struct go7007 *go, int region,
332 struct v4l2_clip *clip_list)
334 struct v4l2_clip clip, *clip_ptr;
335 int x, y, mbnum;
337 /* Check if coordinates are OK and if any macroblocks are already
338 * used by other regions (besides 0) */
339 clip_ptr = clip_list;
340 while (clip_ptr) {
341 if (copy_from_user(&clip, clip_ptr, sizeof(clip)))
342 return -EFAULT;
343 if (clip.c.left < 0 || (clip.c.left & 0xF) ||
344 clip.c.width <= 0 || (clip.c.width & 0xF))
345 return -EINVAL;
346 if (clip.c.left + clip.c.width > go->width)
347 return -EINVAL;
348 if (clip.c.top < 0 || (clip.c.top & 0xF) ||
349 clip.c.height <= 0 || (clip.c.height & 0xF))
350 return -EINVAL;
351 if (clip.c.top + clip.c.height > go->height)
352 return -EINVAL;
353 for (y = 0; y < clip.c.height; y += 16)
354 for (x = 0; x < clip.c.width; x += 16) {
355 mbnum = (go->width >> 4) *
356 ((clip.c.top + y) >> 4) +
357 ((clip.c.left + x) >> 4);
358 if (go->modet_map[mbnum] != 0 &&
359 go->modet_map[mbnum] != region)
360 return -EBUSY;
362 clip_ptr = clip.next;
365 /* Clear old region macroblocks */
366 for (mbnum = 0; mbnum < 1624; ++mbnum)
367 if (go->modet_map[mbnum] == region)
368 go->modet_map[mbnum] = 0;
370 /* Claim macroblocks in this list */
371 clip_ptr = clip_list;
372 while (clip_ptr) {
373 if (copy_from_user(&clip, clip_ptr, sizeof(clip)))
374 return -EFAULT;
375 for (y = 0; y < clip.c.height; y += 16)
376 for (x = 0; x < clip.c.width; x += 16) {
377 mbnum = (go->width >> 4) *
378 ((clip.c.top + y) >> 4) +
379 ((clip.c.left + x) >> 4);
380 go->modet_map[mbnum] = region;
382 clip_ptr = clip.next;
384 return 0;
387 static int mpeg_queryctrl(u32 id, struct v4l2_queryctrl *ctrl)
389 static const u32 user_ctrls[] = {
390 V4L2_CID_USER_CLASS,
393 static const u32 mpeg_ctrls[] = {
394 V4L2_CID_MPEG_CLASS,
395 V4L2_CID_MPEG_STREAM_TYPE,
396 V4L2_CID_MPEG_VIDEO_ENCODING,
397 V4L2_CID_MPEG_VIDEO_ASPECT,
398 V4L2_CID_MPEG_VIDEO_GOP_SIZE,
399 V4L2_CID_MPEG_VIDEO_GOP_CLOSURE,
400 V4L2_CID_MPEG_VIDEO_BITRATE,
403 static const u32 *ctrl_classes[] = {
404 user_ctrls,
405 mpeg_ctrls,
406 NULL
409 /* The ctrl may already contain the queried i2c controls,
410 * query the mpeg controls if the existing ctrl id is
411 * greater than the next mpeg ctrl id.
413 id = v4l2_ctrl_next(ctrl_classes, id);
414 if (id >= ctrl->id && ctrl->name[0])
415 return 0;
417 memset(ctrl, 0, sizeof(*ctrl));
418 ctrl->id = id;
420 switch (ctrl->id) {
421 case V4L2_CID_USER_CLASS:
422 case V4L2_CID_MPEG_CLASS:
423 return v4l2_ctrl_query_fill_std(ctrl);
424 case V4L2_CID_MPEG_STREAM_TYPE:
425 return v4l2_ctrl_query_fill(ctrl,
426 V4L2_MPEG_STREAM_TYPE_MPEG2_DVD,
427 V4L2_MPEG_STREAM_TYPE_MPEG_ELEM, 1,
428 V4L2_MPEG_STREAM_TYPE_MPEG_ELEM);
429 case V4L2_CID_MPEG_VIDEO_ENCODING:
430 return v4l2_ctrl_query_fill(ctrl,
431 V4L2_MPEG_VIDEO_ENCODING_MPEG_1,
432 V4L2_MPEG_VIDEO_ENCODING_MPEG_4, 1,
433 V4L2_MPEG_VIDEO_ENCODING_MPEG_2);
434 case V4L2_CID_MPEG_VIDEO_ASPECT:
435 return v4l2_ctrl_query_fill(ctrl,
436 V4L2_MPEG_VIDEO_ASPECT_1x1,
437 V4L2_MPEG_VIDEO_ASPECT_16x9, 1,
438 V4L2_MPEG_VIDEO_ASPECT_1x1);
439 case V4L2_CID_MPEG_VIDEO_GOP_SIZE:
440 case V4L2_CID_MPEG_VIDEO_GOP_CLOSURE:
441 return v4l2_ctrl_query_fill_std(ctrl);
442 case V4L2_CID_MPEG_VIDEO_BITRATE:
443 return v4l2_ctrl_query_fill(ctrl,
444 64000,
445 10000000, 1,
446 9800000);
447 default:
448 break;
450 return -EINVAL;
453 static int mpeg_s_control(struct v4l2_control *ctrl, struct go7007 *go)
455 /* pretty sure we can't change any of these while streaming */
456 if (go->streaming)
457 return -EBUSY;
459 switch (ctrl->id) {
460 case V4L2_CID_MPEG_STREAM_TYPE:
461 switch (ctrl->value) {
462 case V4L2_MPEG_STREAM_TYPE_MPEG2_DVD:
463 go->format = GO7007_FORMAT_MPEG2;
464 go->bitrate = 9800000;
465 go->gop_size = 15;
466 go->pali = 0x48;
467 go->closed_gop = 1;
468 go->repeat_seqhead = 0;
469 go->seq_header_enable = 1;
470 go->gop_header_enable = 1;
471 go->dvd_mode = 1;
472 break;
473 case V4L2_MPEG_STREAM_TYPE_MPEG_ELEM:
474 /* todo: */
475 break;
476 default:
477 return -EINVAL;
479 break;
480 case V4L2_CID_MPEG_VIDEO_ENCODING:
481 switch (ctrl->value) {
482 case V4L2_MPEG_VIDEO_ENCODING_MPEG_1:
483 go->format = GO7007_FORMAT_MPEG1;
484 go->pali = 0;
485 break;
486 case V4L2_MPEG_VIDEO_ENCODING_MPEG_2:
487 go->format = GO7007_FORMAT_MPEG2;
488 /*if (mpeg->pali >> 24 == 2)
489 go->pali = mpeg->pali & 0xff;
490 else*/
491 go->pali = 0x48;
492 break;
493 case V4L2_MPEG_VIDEO_ENCODING_MPEG_4:
494 go->format = GO7007_FORMAT_MPEG4;
495 /*if (mpeg->pali >> 24 == 4)
496 go->pali = mpeg->pali & 0xff;
497 else*/
498 go->pali = 0xf5;
499 break;
500 default:
501 return -EINVAL;
503 go->gop_header_enable =
504 /*mpeg->flags & GO7007_MPEG_OMIT_GOP_HEADER
505 ? 0 :*/ 1;
506 /*if (mpeg->flags & GO7007_MPEG_REPEAT_SEQHEADER)
507 go->repeat_seqhead = 1;
508 else*/
509 go->repeat_seqhead = 0;
510 go->dvd_mode = 0;
511 break;
512 case V4L2_CID_MPEG_VIDEO_ASPECT:
513 if (go->format == GO7007_FORMAT_MJPEG)
514 return -EINVAL;
515 switch (ctrl->value) {
516 case V4L2_MPEG_VIDEO_ASPECT_1x1:
517 go->aspect_ratio = GO7007_RATIO_1_1;
518 break;
519 case V4L2_MPEG_VIDEO_ASPECT_4x3:
520 go->aspect_ratio = GO7007_RATIO_4_3;
521 break;
522 case V4L2_MPEG_VIDEO_ASPECT_16x9:
523 go->aspect_ratio = GO7007_RATIO_16_9;
524 break;
525 case V4L2_MPEG_VIDEO_ASPECT_221x100:
526 default:
527 return -EINVAL;
529 break;
530 case V4L2_CID_MPEG_VIDEO_GOP_SIZE:
531 go->gop_size = ctrl->value;
532 break;
533 case V4L2_CID_MPEG_VIDEO_GOP_CLOSURE:
534 if (ctrl->value != 0 && ctrl->value != 1)
535 return -EINVAL;
536 go->closed_gop = ctrl->value;
537 break;
538 case V4L2_CID_MPEG_VIDEO_BITRATE:
539 /* Upper bound is kind of arbitrary here */
540 if (ctrl->value < 64000 || ctrl->value > 10000000)
541 return -EINVAL;
542 go->bitrate = ctrl->value;
543 break;
544 default:
545 return -EINVAL;
547 return 0;
550 static int mpeg_g_control(struct v4l2_control *ctrl, struct go7007 *go)
552 switch (ctrl->id) {
553 case V4L2_CID_MPEG_STREAM_TYPE:
554 if (go->dvd_mode)
555 ctrl->value = V4L2_MPEG_STREAM_TYPE_MPEG2_DVD;
556 else
557 ctrl->value = V4L2_MPEG_STREAM_TYPE_MPEG_ELEM;
558 break;
559 case V4L2_CID_MPEG_VIDEO_ENCODING:
560 switch (go->format) {
561 case GO7007_FORMAT_MPEG1:
562 ctrl->value = V4L2_MPEG_VIDEO_ENCODING_MPEG_1;
563 break;
564 case GO7007_FORMAT_MPEG2:
565 ctrl->value = V4L2_MPEG_VIDEO_ENCODING_MPEG_2;
566 break;
567 case GO7007_FORMAT_MPEG4:
568 ctrl->value = V4L2_MPEG_VIDEO_ENCODING_MPEG_4;
569 break;
570 default:
571 return -EINVAL;
573 break;
574 case V4L2_CID_MPEG_VIDEO_ASPECT:
575 switch (go->aspect_ratio) {
576 case GO7007_RATIO_1_1:
577 ctrl->value = V4L2_MPEG_VIDEO_ASPECT_1x1;
578 break;
579 case GO7007_RATIO_4_3:
580 ctrl->value = V4L2_MPEG_VIDEO_ASPECT_4x3;
581 break;
582 case GO7007_RATIO_16_9:
583 ctrl->value = V4L2_MPEG_VIDEO_ASPECT_16x9;
584 break;
585 default:
586 return -EINVAL;
588 break;
589 case V4L2_CID_MPEG_VIDEO_GOP_SIZE:
590 ctrl->value = go->gop_size;
591 break;
592 case V4L2_CID_MPEG_VIDEO_GOP_CLOSURE:
593 ctrl->value = go->closed_gop;
594 break;
595 case V4L2_CID_MPEG_VIDEO_BITRATE:
596 ctrl->value = go->bitrate;
597 break;
598 default:
599 return -EINVAL;
601 return 0;
603 #endif
605 static int vidioc_querycap(struct file *file, void *priv,
606 struct v4l2_capability *cap)
608 struct go7007_file *gofh = priv;
609 struct go7007 *go = gofh->go;
611 strlcpy(cap->driver, "go7007", sizeof(cap->driver));
612 strlcpy(cap->card, go->name, sizeof(cap->card));
613 #if 0
614 strlcpy(cap->bus_info, dev_name(&dev->udev->dev), sizeof(cap->bus_info));
615 #endif
617 cap->version = KERNEL_VERSION(0, 9, 8);
619 cap->capabilities = V4L2_CAP_VIDEO_CAPTURE |
620 V4L2_CAP_STREAMING; /* | V4L2_CAP_AUDIO; */
622 if (go->board_info->flags & GO7007_BOARD_HAS_TUNER)
623 cap->capabilities |= V4L2_CAP_TUNER;
625 return 0;
628 static int vidioc_enum_fmt_vid_cap(struct file *file, void *priv,
629 struct v4l2_fmtdesc *fmt)
631 char *desc = NULL;
633 switch (fmt->index) {
634 case 0:
635 fmt->pixelformat = V4L2_PIX_FMT_MJPEG;
636 desc = "Motion-JPEG";
637 break;
638 case 1:
639 fmt->pixelformat = V4L2_PIX_FMT_MPEG;
640 desc = "MPEG1/MPEG2/MPEG4";
641 break;
642 default:
643 return -EINVAL;
645 fmt->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
646 fmt->flags = V4L2_FMT_FLAG_COMPRESSED;
648 strncpy(fmt->description, desc, sizeof(fmt->description));
650 return 0;
653 static int vidioc_g_fmt_vid_cap(struct file *file, void *priv,
654 struct v4l2_format *fmt)
656 struct go7007_file *gofh = priv;
657 struct go7007 *go = gofh->go;
659 fmt->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
660 fmt->fmt.pix.width = go->width;
661 fmt->fmt.pix.height = go->height;
662 fmt->fmt.pix.pixelformat = (go->format == GO7007_FORMAT_MJPEG) ?
663 V4L2_PIX_FMT_MJPEG : V4L2_PIX_FMT_MPEG;
664 fmt->fmt.pix.field = V4L2_FIELD_NONE;
665 fmt->fmt.pix.bytesperline = 0;
666 fmt->fmt.pix.sizeimage = GO7007_BUF_SIZE;
667 fmt->fmt.pix.colorspace = V4L2_COLORSPACE_SMPTE170M;
669 return 0;
672 static int vidioc_try_fmt_vid_cap(struct file *file, void *priv,
673 struct v4l2_format *fmt)
675 struct go7007_file *gofh = priv;
676 struct go7007 *go = gofh->go;
678 return set_capture_size(go, fmt, 1);
681 static int vidioc_s_fmt_vid_cap(struct file *file, void *priv,
682 struct v4l2_format *fmt)
684 struct go7007_file *gofh = priv;
685 struct go7007 *go = gofh->go;
687 if (go->streaming)
688 return -EBUSY;
690 return set_capture_size(go, fmt, 0);
693 static int vidioc_reqbufs(struct file *file, void *priv,
694 struct v4l2_requestbuffers *req)
696 struct go7007_file *gofh = priv;
697 struct go7007 *go = gofh->go;
698 int retval = -EBUSY;
699 unsigned int count, i;
701 if (go->streaming)
702 return retval;
704 if (req->type != V4L2_BUF_TYPE_VIDEO_CAPTURE ||
705 req->memory != V4L2_MEMORY_MMAP)
706 return -EINVAL;
708 down(&gofh->lock);
709 for (i = 0; i < gofh->buf_count; ++i)
710 if (gofh->bufs[i].mapped > 0)
711 goto unlock_and_return;
713 down(&go->hw_lock);
714 if (go->in_use > 0 && gofh->buf_count == 0) {
715 up(&go->hw_lock);
716 goto unlock_and_return;
719 if (gofh->buf_count > 0)
720 kfree(gofh->bufs);
722 retval = -ENOMEM;
723 count = req->count;
724 if (count > 0) {
725 if (count < 2)
726 count = 2;
727 if (count > 32)
728 count = 32;
730 gofh->bufs = kmalloc(count * sizeof(struct go7007_buffer),
731 GFP_KERNEL);
733 if (!gofh->bufs) {
734 up(&go->hw_lock);
735 goto unlock_and_return;
738 memset(gofh->bufs, 0, count * sizeof(struct go7007_buffer));
740 for (i = 0; i < count; ++i) {
741 gofh->bufs[i].go = go;
742 gofh->bufs[i].index = i;
743 gofh->bufs[i].state = BUF_STATE_IDLE;
744 gofh->bufs[i].mapped = 0;
747 go->in_use = 1;
748 } else {
749 go->in_use = 0;
752 gofh->buf_count = count;
753 up(&go->hw_lock);
754 up(&gofh->lock);
756 memset(req, 0, sizeof(*req));
758 req->count = count;
759 req->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
760 req->memory = V4L2_MEMORY_MMAP;
762 return 0;
764 unlock_and_return:
765 up(&gofh->lock);
766 return retval;
769 static int vidioc_querybuf(struct file *file, void *priv,
770 struct v4l2_buffer *buf)
772 struct go7007_file *gofh = priv;
773 int retval = -EINVAL;
774 unsigned int index;
776 if (buf->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
777 return retval;
779 index = buf->index;
781 down(&gofh->lock);
782 if (index >= gofh->buf_count)
783 goto unlock_and_return;
785 memset(buf, 0, sizeof(*buf));
786 buf->index = index;
787 buf->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
789 switch (gofh->bufs[index].state) {
790 case BUF_STATE_QUEUED:
791 buf->flags = V4L2_BUF_FLAG_QUEUED;
792 break;
793 case BUF_STATE_DONE:
794 buf->flags = V4L2_BUF_FLAG_DONE;
795 break;
796 default:
797 buf->flags = 0;
800 if (gofh->bufs[index].mapped)
801 buf->flags |= V4L2_BUF_FLAG_MAPPED;
802 buf->memory = V4L2_MEMORY_MMAP;
803 buf->m.offset = index * GO7007_BUF_SIZE;
804 buf->length = GO7007_BUF_SIZE;
805 up(&gofh->lock);
807 return 0;
809 unlock_and_return:
810 up(&gofh->lock);
811 return retval;
814 static int vidioc_qbuf(struct file *file, void *priv, struct v4l2_buffer *buf)
816 struct go7007_file *gofh = priv;
817 struct go7007 *go = gofh->go;
818 struct go7007_buffer *gobuf;
819 unsigned long flags;
820 int retval = -EINVAL;
821 int ret;
823 if (buf->type != V4L2_BUF_TYPE_VIDEO_CAPTURE ||
824 buf->memory != V4L2_MEMORY_MMAP)
825 return retval;
827 down(&gofh->lock);
828 if (buf->index < 0 || buf->index >= gofh->buf_count)
829 goto unlock_and_return;
831 gobuf = &gofh->bufs[buf->index];
832 if (!gobuf->mapped)
833 goto unlock_and_return;
835 retval = -EBUSY;
836 if (gobuf->state != BUF_STATE_IDLE)
837 goto unlock_and_return;
839 /* offset will be 0 until we really support USERPTR streaming */
840 gobuf->offset = gobuf->user_addr & ~PAGE_MASK;
841 gobuf->bytesused = 0;
842 gobuf->frame_offset = 0;
843 gobuf->modet_active = 0;
844 if (gobuf->offset > 0)
845 gobuf->page_count = GO7007_BUF_PAGES + 1;
846 else
847 gobuf->page_count = GO7007_BUF_PAGES;
849 retval = -ENOMEM;
850 down_read(&current->mm->mmap_sem);
851 ret = get_user_pages(current, current->mm,
852 gobuf->user_addr & PAGE_MASK, gobuf->page_count,
853 1, 1, gobuf->pages, NULL);
854 up_read(&current->mm->mmap_sem);
856 if (ret != gobuf->page_count) {
857 int i;
858 for (i = 0; i < ret; ++i)
859 page_cache_release(gobuf->pages[i]);
860 gobuf->page_count = 0;
861 goto unlock_and_return;
864 gobuf->state = BUF_STATE_QUEUED;
865 spin_lock_irqsave(&go->spinlock, flags);
866 list_add_tail(&gobuf->stream, &go->stream);
867 spin_unlock_irqrestore(&go->spinlock, flags);
868 up(&gofh->lock);
870 return 0;
872 unlock_and_return:
873 up(&gofh->lock);
874 return retval;
878 static int vidioc_dqbuf(struct file *file, void *priv, struct v4l2_buffer *buf)
880 struct go7007_file *gofh = priv;
881 struct go7007 *go = gofh->go;
882 struct go7007_buffer *gobuf;
883 int retval = -EINVAL;
884 unsigned long flags;
885 u32 frame_type_flag;
886 DEFINE_WAIT(wait);
888 if (buf->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
889 return retval;
890 if (buf->memory != V4L2_MEMORY_MMAP)
891 return retval;
893 down(&gofh->lock);
894 if (list_empty(&go->stream))
895 goto unlock_and_return;
896 gobuf = list_entry(go->stream.next,
897 struct go7007_buffer, stream);
899 retval = -EAGAIN;
900 if (gobuf->state != BUF_STATE_DONE &&
901 !(file->f_flags & O_NONBLOCK)) {
902 for (;;) {
903 prepare_to_wait(&go->frame_waitq, &wait,
904 TASK_INTERRUPTIBLE);
905 if (gobuf->state == BUF_STATE_DONE)
906 break;
907 if (signal_pending(current)) {
908 retval = -ERESTARTSYS;
909 break;
911 schedule();
913 finish_wait(&go->frame_waitq, &wait);
915 if (gobuf->state != BUF_STATE_DONE)
916 goto unlock_and_return;
918 spin_lock_irqsave(&go->spinlock, flags);
919 deactivate_buffer(gobuf);
920 spin_unlock_irqrestore(&go->spinlock, flags);
921 frame_type_flag = get_frame_type_flag(gobuf, go->format);
922 gobuf->state = BUF_STATE_IDLE;
924 memset(buf, 0, sizeof(*buf));
925 buf->index = gobuf->index;
926 buf->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
927 buf->bytesused = gobuf->bytesused;
928 buf->flags = V4L2_BUF_FLAG_MAPPED | frame_type_flag;
929 buf->field = V4L2_FIELD_NONE;
930 buf->timestamp = gobuf->timestamp;
931 buf->sequence = gobuf->seq;
932 buf->memory = V4L2_MEMORY_MMAP;
933 buf->m.offset = gobuf->index * GO7007_BUF_SIZE;
934 buf->length = GO7007_BUF_SIZE;
935 buf->reserved = gobuf->modet_active;
937 up(&gofh->lock);
938 return 0;
940 unlock_and_return:
941 up(&gofh->lock);
942 return retval;
945 static int vidioc_streamon(struct file *file, void *priv,
946 enum v4l2_buf_type type)
948 struct go7007_file *gofh = priv;
949 struct go7007 *go = gofh->go;
950 int retval = 0;
952 if (type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
953 return -EINVAL;
955 down(&gofh->lock);
956 down(&go->hw_lock);
958 if (!go->streaming) {
959 go->streaming = 1;
960 go->next_seq = 0;
961 go->active_buf = NULL;
962 if (go7007_start_encoder(go) < 0)
963 retval = -EIO;
964 else
965 retval = 0;
967 up(&go->hw_lock);
968 up(&gofh->lock);
970 return retval;
973 static int vidioc_streamoff(struct file *file, void *priv,
974 enum v4l2_buf_type type)
976 struct go7007_file *gofh = priv;
977 struct go7007 *go = gofh->go;
979 if (type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
980 return -EINVAL;
981 down(&gofh->lock);
982 go7007_streamoff(go);
983 up(&gofh->lock);
985 return 0;
988 static int vidioc_queryctrl(struct file *file, void *priv,
989 struct v4l2_queryctrl *query)
991 struct go7007_file *gofh = priv;
992 struct go7007 *go = gofh->go;
994 if (!go->i2c_adapter_online)
995 return -EIO;
997 i2c_clients_command(&go->i2c_adapter, VIDIOC_QUERYCTRL, query);
999 return (!query->name[0]) ? -EINVAL : 0;
1002 static int vidioc_g_ctrl(struct file *file, void *priv,
1003 struct v4l2_control *ctrl)
1005 struct go7007_file *gofh = priv;
1006 struct go7007 *go = gofh->go;
1007 struct v4l2_queryctrl query;
1009 if (!go->i2c_adapter_online)
1010 return -EIO;
1012 memset(&query, 0, sizeof(query));
1013 query.id = ctrl->id;
1014 i2c_clients_command(&go->i2c_adapter, VIDIOC_QUERYCTRL, &query);
1015 if (query.name[0] == 0)
1016 return -EINVAL;
1017 i2c_clients_command(&go->i2c_adapter, VIDIOC_G_CTRL, ctrl);
1019 return 0;
1022 static int vidioc_s_ctrl(struct file *file, void *priv,
1023 struct v4l2_control *ctrl)
1025 struct go7007_file *gofh = priv;
1026 struct go7007 *go = gofh->go;
1027 struct v4l2_queryctrl query;
1029 if (!go->i2c_adapter_online)
1030 return -EIO;
1032 memset(&query, 0, sizeof(query));
1033 query.id = ctrl->id;
1034 i2c_clients_command(&go->i2c_adapter, VIDIOC_QUERYCTRL, &query);
1035 if (query.name[0] == 0)
1036 return -EINVAL;
1037 i2c_clients_command(&go->i2c_adapter, VIDIOC_S_CTRL, ctrl);
1039 return 0;
1042 static int vidioc_g_parm(struct file *filp, void *priv,
1043 struct v4l2_streamparm *parm)
1045 struct go7007_file *gofh = priv;
1046 struct go7007 *go = gofh->go;
1047 struct v4l2_fract timeperframe = {
1048 .numerator = 1001 * go->fps_scale,
1049 .denominator = go->sensor_framerate,
1052 if (parm->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
1053 return -EINVAL;
1055 parm->parm.capture.capability |= V4L2_CAP_TIMEPERFRAME;
1056 parm->parm.capture.timeperframe = timeperframe;
1058 return 0;
1061 static int vidioc_s_parm(struct file *filp, void *priv,
1062 struct v4l2_streamparm *parm)
1064 struct go7007_file *gofh = priv;
1065 struct go7007 *go = gofh->go;
1066 unsigned int n, d;
1068 if (parm->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
1069 return -EINVAL;
1070 if (parm->parm.capture.capturemode != 0)
1071 return -EINVAL;
1073 n = go->sensor_framerate *
1074 parm->parm.capture.timeperframe.numerator;
1075 d = 1001 * parm->parm.capture.timeperframe.denominator;
1076 if (n != 0 && d != 0 && n > d)
1077 go->fps_scale = (n + d/2) / d;
1078 else
1079 go->fps_scale = 1;
1081 return 0;
1084 /* VIDIOC_ENUMSTD on go7007 were used for enumberating the supported fps and
1085 its resolution, when the device is not connected to TV.
1086 This were an API abuse, probably used by the lack of specific IOCTL's to
1087 enumberate it, by the time the driver were written.
1089 However, since kernel 2.6.19, two new ioctls (VIDIOC_ENUM_FRAMEINTERVALS
1090 and VIDIOC_ENUM_FRAMESIZES) were added for this purpose.
1092 The two functions bellow implements the newer ioctls
1094 static int vidioc_enum_framesizes(struct file *filp, void *priv,
1095 struct v4l2_frmsizeenum *fsize)
1097 struct go7007_file *gofh = priv;
1098 struct go7007 *go = gofh->go;
1100 /* Return -EINVAL, if it is a TV board */
1101 if ((go->board_info->flags & GO7007_BOARD_HAS_TUNER) ||
1102 (go->board_info->sensor_flags & GO7007_SENSOR_TV))
1103 return -EINVAL;
1105 if (fsize->index > 0)
1106 return -EINVAL;
1108 fsize->type = V4L2_FRMSIZE_TYPE_DISCRETE;
1109 fsize->discrete.width = go->board_info->sensor_width;
1110 fsize->discrete.height = go->board_info->sensor_height;
1112 return 0;
1115 static int vidioc_enum_frameintervals(struct file *filp, void *priv,
1116 struct v4l2_frmivalenum *fival)
1118 struct go7007_file *gofh = priv;
1119 struct go7007 *go = gofh->go;
1121 /* Return -EINVAL, if it is a TV board */
1122 if ((go->board_info->flags & GO7007_BOARD_HAS_TUNER) ||
1123 (go->board_info->sensor_flags & GO7007_SENSOR_TV))
1124 return -EINVAL;
1126 if (fival->index > 0)
1127 return -EINVAL;
1129 fival->type = V4L2_FRMIVAL_TYPE_DISCRETE;
1130 fival->discrete.numerator = 1001;
1131 fival->discrete.denominator = go->board_info->sensor_framerate;
1133 return 0;
1136 static int vidioc_s_std(struct file *file, void *priv, v4l2_std_id *std)
1138 struct go7007_file *gofh = priv;
1139 struct go7007 *go = gofh->go;
1141 if (go->streaming)
1142 return -EBUSY;
1144 if (!(go->board_info->sensor_flags & GO7007_SENSOR_TV) &&
1145 *std != 0)
1146 return -EINVAL;
1148 if (*std == 0)
1149 return -EINVAL;
1151 if ((go->board_info->flags & GO7007_BOARD_HAS_TUNER) &&
1152 go->input == go->board_info->num_inputs - 1) {
1153 if (!go->i2c_adapter_online)
1154 return -EIO;
1155 i2c_clients_command(&go->i2c_adapter,
1156 VIDIOC_S_STD, std);
1157 if (!*std) /* hack to indicate EINVAL from tuner */
1158 return -EINVAL;
1161 if (*std & V4L2_STD_NTSC) {
1162 go->standard = GO7007_STD_NTSC;
1163 go->sensor_framerate = 30000;
1164 } else if (*std & V4L2_STD_PAL) {
1165 go->standard = GO7007_STD_PAL;
1166 go->sensor_framerate = 25025;
1167 } else if (*std & V4L2_STD_SECAM) {
1168 go->standard = GO7007_STD_PAL;
1169 go->sensor_framerate = 25025;
1170 } else
1171 return -EINVAL;
1173 if (go->i2c_adapter_online)
1174 i2c_clients_command(&go->i2c_adapter,
1175 VIDIOC_S_STD, std);
1176 set_capture_size(go, NULL, 0);
1178 return 0;
1181 #if 0
1182 case VIDIOC_QUERYSTD:
1184 v4l2_std_id *std = arg;
1186 if ((go->board_info->flags & GO7007_BOARD_HAS_TUNER) &&
1187 go->input == go->board_info->num_inputs - 1) {
1188 if (!go->i2c_adapter_online)
1189 return -EIO;
1190 i2c_clients_command(&go->i2c_adapter,
1191 VIDIOC_QUERYSTD, arg);
1192 } else if (go->board_info->sensor_flags & GO7007_SENSOR_TV)
1193 *std = V4L2_STD_NTSC | V4L2_STD_PAL | V4L2_STD_SECAM;
1194 else
1195 *std = 0;
1196 return 0;
1198 #endif
1200 static int vidioc_enum_input(struct file *file, void *priv,
1201 struct v4l2_input *inp)
1203 struct go7007_file *gofh = priv;
1204 struct go7007 *go = gofh->go;
1206 if (inp->index >= go->board_info->num_inputs)
1207 return -EINVAL;
1209 strncpy(inp->name, go->board_info->inputs[inp->index].name,
1210 sizeof(inp->name));
1212 /* If this board has a tuner, it will be the last input */
1213 if ((go->board_info->flags & GO7007_BOARD_HAS_TUNER) &&
1214 inp->index == go->board_info->num_inputs - 1)
1215 inp->type = V4L2_INPUT_TYPE_TUNER;
1216 else
1217 inp->type = V4L2_INPUT_TYPE_CAMERA;
1219 inp->audioset = 0;
1220 inp->tuner = 0;
1221 if (go->board_info->sensor_flags & GO7007_SENSOR_TV)
1222 inp->std = V4L2_STD_NTSC | V4L2_STD_PAL |
1223 V4L2_STD_SECAM;
1224 else
1225 inp->std = 0;
1227 return 0;
1231 static int vidioc_g_input(struct file *file, void *priv, unsigned int *input)
1233 struct go7007_file *gofh = priv;
1234 struct go7007 *go = gofh->go;
1236 *input = go->input;
1238 return 0;
1241 static int vidioc_s_input(struct file *file, void *priv, unsigned int input)
1243 struct go7007_file *gofh = priv;
1244 struct go7007 *go = gofh->go;
1246 if (input >= go->board_info->num_inputs)
1247 return -EINVAL;
1248 if (go->streaming)
1249 return -EBUSY;
1251 go->input = input;
1252 if (go->i2c_adapter_online) {
1253 i2c_clients_command(&go->i2c_adapter, VIDIOC_S_INPUT,
1254 &go->board_info->inputs[input].video_input);
1255 i2c_clients_command(&go->i2c_adapter, VIDIOC_S_AUDIO,
1256 &go->board_info->inputs[input].audio_input);
1259 return 0;
1262 static int vidioc_g_tuner(struct file *file, void *priv,
1263 struct v4l2_tuner *t)
1265 struct go7007_file *gofh = priv;
1266 struct go7007 *go = gofh->go;
1268 if (!(go->board_info->flags & GO7007_BOARD_HAS_TUNER))
1269 return -EINVAL;
1270 if (t->index != 0)
1271 return -EINVAL;
1272 if (!go->i2c_adapter_online)
1273 return -EIO;
1275 i2c_clients_command(&go->i2c_adapter, VIDIOC_G_TUNER, t);
1277 t->index = 0;
1278 return 0;
1281 static int vidioc_s_tuner(struct file *file, void *priv,
1282 struct v4l2_tuner *t)
1284 struct go7007_file *gofh = priv;
1285 struct go7007 *go = gofh->go;
1287 if (!(go->board_info->flags & GO7007_BOARD_HAS_TUNER))
1288 return -EINVAL;
1289 if (t->index != 0)
1290 return -EINVAL;
1291 if (!go->i2c_adapter_online)
1292 return -EIO;
1294 switch (go->board_id) {
1295 case GO7007_BOARDID_PX_TV402U_NA:
1296 case GO7007_BOARDID_PX_TV402U_JP:
1297 /* No selectable options currently */
1298 if (t->audmode != V4L2_TUNER_MODE_STEREO)
1299 return -EINVAL;
1300 break;
1303 i2c_clients_command(&go->i2c_adapter, VIDIOC_S_TUNER, t);
1305 return 0;
1308 static int vidioc_g_frequency(struct file *file, void *priv,
1309 struct v4l2_frequency *f)
1311 struct go7007_file *gofh = priv;
1312 struct go7007 *go = gofh->go;
1314 if (!(go->board_info->flags & GO7007_BOARD_HAS_TUNER))
1315 return -EINVAL;
1316 if (!go->i2c_adapter_online)
1317 return -EIO;
1319 f->type = V4L2_TUNER_ANALOG_TV;
1320 i2c_clients_command(&go->i2c_adapter, VIDIOC_G_FREQUENCY, f);
1321 return 0;
1324 static int vidioc_s_frequency(struct file *file, void *priv,
1325 struct v4l2_frequency *f)
1327 struct go7007_file *gofh = priv;
1328 struct go7007 *go = gofh->go;
1330 if (!(go->board_info->flags & GO7007_BOARD_HAS_TUNER))
1331 return -EINVAL;
1332 if (!go->i2c_adapter_online)
1333 return -EIO;
1335 i2c_clients_command(&go->i2c_adapter, VIDIOC_S_FREQUENCY, f);
1337 return 0;
1340 static int vidioc_cropcap(struct file *file, void *priv,
1341 struct v4l2_cropcap *cropcap)
1343 struct go7007_file *gofh = priv;
1344 struct go7007 *go = gofh->go;
1346 if (cropcap->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
1347 return -EINVAL;
1349 /* These specify the raw input of the sensor */
1350 switch (go->standard) {
1351 case GO7007_STD_NTSC:
1352 cropcap->bounds.top = 0;
1353 cropcap->bounds.left = 0;
1354 cropcap->bounds.width = 720;
1355 cropcap->bounds.height = 480;
1356 cropcap->defrect.top = 0;
1357 cropcap->defrect.left = 0;
1358 cropcap->defrect.width = 720;
1359 cropcap->defrect.height = 480;
1360 break;
1361 case GO7007_STD_PAL:
1362 cropcap->bounds.top = 0;
1363 cropcap->bounds.left = 0;
1364 cropcap->bounds.width = 720;
1365 cropcap->bounds.height = 576;
1366 cropcap->defrect.top = 0;
1367 cropcap->defrect.left = 0;
1368 cropcap->defrect.width = 720;
1369 cropcap->defrect.height = 576;
1370 break;
1371 case GO7007_STD_OTHER:
1372 cropcap->bounds.top = 0;
1373 cropcap->bounds.left = 0;
1374 cropcap->bounds.width = go->board_info->sensor_width;
1375 cropcap->bounds.height = go->board_info->sensor_height;
1376 cropcap->defrect.top = 0;
1377 cropcap->defrect.left = 0;
1378 cropcap->defrect.width = go->board_info->sensor_width;
1379 cropcap->defrect.height = go->board_info->sensor_height;
1380 break;
1383 return 0;
1386 static int vidioc_g_crop(struct file *file, void *priv, struct v4l2_crop *crop)
1388 struct go7007_file *gofh = priv;
1389 struct go7007 *go = gofh->go;
1391 if (crop->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
1392 return -EINVAL;
1394 crop->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
1396 /* These specify the raw input of the sensor */
1397 switch (go->standard) {
1398 case GO7007_STD_NTSC:
1399 crop->c.top = 0;
1400 crop->c.left = 0;
1401 crop->c.width = 720;
1402 crop->c.height = 480;
1403 break;
1404 case GO7007_STD_PAL:
1405 crop->c.top = 0;
1406 crop->c.left = 0;
1407 crop->c.width = 720;
1408 crop->c.height = 576;
1409 break;
1410 case GO7007_STD_OTHER:
1411 crop->c.top = 0;
1412 crop->c.left = 0;
1413 crop->c.width = go->board_info->sensor_width;
1414 crop->c.height = go->board_info->sensor_height;
1415 break;
1418 return 0;
1421 /* FIXME: vidioc_s_crop is not really implemented!!!
1423 static int vidioc_s_crop(struct file *file, void *priv, struct v4l2_crop *crop)
1425 if (crop->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
1426 return -EINVAL;
1428 return 0;
1431 static int vidioc_g_jpegcomp(struct file *file, void *priv,
1432 struct v4l2_jpegcompression *params)
1434 memset(params, 0, sizeof(*params));
1435 params->quality = 50; /* ?? */
1436 params->jpeg_markers = V4L2_JPEG_MARKER_DHT |
1437 V4L2_JPEG_MARKER_DQT;
1439 return 0;
1442 static int vidioc_s_jpegcomp(struct file *file, void *priv,
1443 struct v4l2_jpegcompression *params)
1445 if (params->quality != 50 ||
1446 params->jpeg_markers != (V4L2_JPEG_MARKER_DHT |
1447 V4L2_JPEG_MARKER_DQT))
1448 return -EINVAL;
1450 return 0;
1453 /* FIXME:
1454 Those ioctls are private, and not needed, since several standard
1455 extended controls already provide streaming control.
1456 So, those ioctls should be converted into vidioc_g_ext_ctrls()
1457 and vidioc_s_ext_ctrls()
1460 #if 0
1461 /* Temporary ioctls for controlling compression characteristics */
1462 case GO7007IOC_S_BITRATE:
1464 int *bitrate = arg;
1466 if (go->streaming)
1467 return -EINVAL;
1468 /* Upper bound is kind of arbitrary here */
1469 if (*bitrate < 64000 || *bitrate > 10000000)
1470 return -EINVAL;
1471 go->bitrate = *bitrate;
1472 return 0;
1474 case GO7007IOC_G_BITRATE:
1476 int *bitrate = arg;
1478 *bitrate = go->bitrate;
1479 return 0;
1481 case GO7007IOC_S_COMP_PARAMS:
1483 struct go7007_comp_params *comp = arg;
1485 if (go->format == GO7007_FORMAT_MJPEG)
1486 return -EINVAL;
1487 if (comp->gop_size > 0)
1488 go->gop_size = comp->gop_size;
1489 else
1490 go->gop_size = go->sensor_framerate / 1000;
1491 if (go->gop_size != 15)
1492 go->dvd_mode = 0;
1493 /*go->ipb = comp->max_b_frames > 0;*/ /* completely untested */
1494 if (go->board_info->sensor_flags & GO7007_SENSOR_TV) {
1495 switch (comp->aspect_ratio) {
1496 case GO7007_ASPECT_RATIO_4_3_NTSC:
1497 case GO7007_ASPECT_RATIO_4_3_PAL:
1498 go->aspect_ratio = GO7007_RATIO_4_3;
1499 break;
1500 case GO7007_ASPECT_RATIO_16_9_NTSC:
1501 case GO7007_ASPECT_RATIO_16_9_PAL:
1502 go->aspect_ratio = GO7007_RATIO_16_9;
1503 break;
1504 default:
1505 go->aspect_ratio = GO7007_RATIO_1_1;
1506 break;
1509 if (comp->flags & GO7007_COMP_OMIT_SEQ_HEADER) {
1510 go->dvd_mode = 0;
1511 go->seq_header_enable = 0;
1512 } else {
1513 go->seq_header_enable = 1;
1515 /* fall-through */
1517 case GO7007IOC_G_COMP_PARAMS:
1519 struct go7007_comp_params *comp = arg;
1521 if (go->format == GO7007_FORMAT_MJPEG)
1522 return -EINVAL;
1523 memset(comp, 0, sizeof(*comp));
1524 comp->gop_size = go->gop_size;
1525 comp->max_b_frames = go->ipb ? 2 : 0;
1526 switch (go->aspect_ratio) {
1527 case GO7007_RATIO_4_3:
1528 if (go->standard == GO7007_STD_NTSC)
1529 comp->aspect_ratio =
1530 GO7007_ASPECT_RATIO_4_3_NTSC;
1531 else
1532 comp->aspect_ratio =
1533 GO7007_ASPECT_RATIO_4_3_PAL;
1534 break;
1535 case GO7007_RATIO_16_9:
1536 if (go->standard == GO7007_STD_NTSC)
1537 comp->aspect_ratio =
1538 GO7007_ASPECT_RATIO_16_9_NTSC;
1539 else
1540 comp->aspect_ratio =
1541 GO7007_ASPECT_RATIO_16_9_PAL;
1542 break;
1543 default:
1544 comp->aspect_ratio = GO7007_ASPECT_RATIO_1_1;
1545 break;
1547 if (go->closed_gop)
1548 comp->flags |= GO7007_COMP_CLOSED_GOP;
1549 if (!go->seq_header_enable)
1550 comp->flags |= GO7007_COMP_OMIT_SEQ_HEADER;
1551 return 0;
1553 case GO7007IOC_S_MPEG_PARAMS:
1555 struct go7007_mpeg_params *mpeg = arg;
1557 if (go->format != GO7007_FORMAT_MPEG1 &&
1558 go->format != GO7007_FORMAT_MPEG2 &&
1559 go->format != GO7007_FORMAT_MPEG4)
1560 return -EINVAL;
1562 if (mpeg->flags & GO7007_MPEG_FORCE_DVD_MODE) {
1563 go->format = GO7007_FORMAT_MPEG2;
1564 go->bitrate = 9800000;
1565 go->gop_size = 15;
1566 go->pali = 0x48;
1567 go->closed_gop = 1;
1568 go->repeat_seqhead = 0;
1569 go->seq_header_enable = 1;
1570 go->gop_header_enable = 1;
1571 go->dvd_mode = 1;
1572 } else {
1573 switch (mpeg->mpeg_video_standard) {
1574 case GO7007_MPEG_VIDEO_MPEG1:
1575 go->format = GO7007_FORMAT_MPEG1;
1576 go->pali = 0;
1577 break;
1578 case GO7007_MPEG_VIDEO_MPEG2:
1579 go->format = GO7007_FORMAT_MPEG2;
1580 if (mpeg->pali >> 24 == 2)
1581 go->pali = mpeg->pali & 0xff;
1582 else
1583 go->pali = 0x48;
1584 break;
1585 case GO7007_MPEG_VIDEO_MPEG4:
1586 go->format = GO7007_FORMAT_MPEG4;
1587 if (mpeg->pali >> 24 == 4)
1588 go->pali = mpeg->pali & 0xff;
1589 else
1590 go->pali = 0xf5;
1591 break;
1592 default:
1593 return -EINVAL;
1595 go->gop_header_enable =
1596 mpeg->flags & GO7007_MPEG_OMIT_GOP_HEADER
1597 ? 0 : 1;
1598 if (mpeg->flags & GO7007_MPEG_REPEAT_SEQHEADER)
1599 go->repeat_seqhead = 1;
1600 else
1601 go->repeat_seqhead = 0;
1602 go->dvd_mode = 0;
1604 /* fall-through */
1606 case GO7007IOC_G_MPEG_PARAMS:
1608 struct go7007_mpeg_params *mpeg = arg;
1610 memset(mpeg, 0, sizeof(*mpeg));
1611 switch (go->format) {
1612 case GO7007_FORMAT_MPEG1:
1613 mpeg->mpeg_video_standard = GO7007_MPEG_VIDEO_MPEG1;
1614 mpeg->pali = 0;
1615 break;
1616 case GO7007_FORMAT_MPEG2:
1617 mpeg->mpeg_video_standard = GO7007_MPEG_VIDEO_MPEG2;
1618 mpeg->pali = GO7007_MPEG_PROFILE(2, go->pali);
1619 break;
1620 case GO7007_FORMAT_MPEG4:
1621 mpeg->mpeg_video_standard = GO7007_MPEG_VIDEO_MPEG4;
1622 mpeg->pali = GO7007_MPEG_PROFILE(4, go->pali);
1623 break;
1624 default:
1625 return -EINVAL;
1627 if (!go->gop_header_enable)
1628 mpeg->flags |= GO7007_MPEG_OMIT_GOP_HEADER;
1629 if (go->repeat_seqhead)
1630 mpeg->flags |= GO7007_MPEG_REPEAT_SEQHEADER;
1631 if (go->dvd_mode)
1632 mpeg->flags |= GO7007_MPEG_FORCE_DVD_MODE;
1633 return 0;
1635 case GO7007IOC_S_MD_PARAMS:
1637 struct go7007_md_params *mdp = arg;
1639 if (mdp->region > 3)
1640 return -EINVAL;
1641 if (mdp->trigger > 0) {
1642 go->modet[mdp->region].pixel_threshold =
1643 mdp->pixel_threshold >> 1;
1644 go->modet[mdp->region].motion_threshold =
1645 mdp->motion_threshold >> 1;
1646 go->modet[mdp->region].mb_threshold =
1647 mdp->trigger >> 1;
1648 go->modet[mdp->region].enable = 1;
1649 } else
1650 go->modet[mdp->region].enable = 0;
1651 /* fall-through */
1653 case GO7007IOC_G_MD_PARAMS:
1655 struct go7007_md_params *mdp = arg;
1656 int region = mdp->region;
1658 if (mdp->region > 3)
1659 return -EINVAL;
1660 memset(mdp, 0, sizeof(struct go7007_md_params));
1661 mdp->region = region;
1662 if (!go->modet[region].enable)
1663 return 0;
1664 mdp->pixel_threshold =
1665 (go->modet[region].pixel_threshold << 1) + 1;
1666 mdp->motion_threshold =
1667 (go->modet[region].motion_threshold << 1) + 1;
1668 mdp->trigger =
1669 (go->modet[region].mb_threshold << 1) + 1;
1670 return 0;
1672 case GO7007IOC_S_MD_REGION:
1674 struct go7007_md_region *region = arg;
1676 if (region->region < 1 || region->region > 3)
1677 return -EINVAL;
1678 return clip_to_modet_map(go, region->region, region->clips);
1680 #endif
1682 static ssize_t go7007_read(struct file *file, char __user *data,
1683 size_t count, loff_t *ppos)
1685 return -EINVAL;
1688 static void go7007_vm_open(struct vm_area_struct *vma)
1690 struct go7007_buffer *gobuf = vma->vm_private_data;
1692 ++gobuf->mapped;
1695 static void go7007_vm_close(struct vm_area_struct *vma)
1697 struct go7007_buffer *gobuf = vma->vm_private_data;
1698 unsigned long flags;
1700 if (--gobuf->mapped == 0) {
1701 spin_lock_irqsave(&gobuf->go->spinlock, flags);
1702 deactivate_buffer(gobuf);
1703 spin_unlock_irqrestore(&gobuf->go->spinlock, flags);
1707 /* Copied from videobuf-dma-sg.c */
1708 static int go7007_vm_fault(struct vm_area_struct *vma, struct vm_fault *vmf)
1710 struct page *page;
1712 page = alloc_page(GFP_USER | __GFP_DMA32);
1713 if (!page)
1714 return VM_FAULT_OOM;
1715 clear_user_highpage(page, (unsigned long)vmf->virtual_address);
1716 vmf->page = page;
1717 return 0;
1720 static struct vm_operations_struct go7007_vm_ops = {
1721 .open = go7007_vm_open,
1722 .close = go7007_vm_close,
1723 .fault = go7007_vm_fault,
1726 static int go7007_mmap(struct file *file, struct vm_area_struct *vma)
1728 struct go7007_file *gofh = file->private_data;
1729 unsigned int index;
1731 if (gofh->go->status != STATUS_ONLINE)
1732 return -EIO;
1733 if (!(vma->vm_flags & VM_SHARED))
1734 return -EINVAL; /* only support VM_SHARED mapping */
1735 if (vma->vm_end - vma->vm_start != GO7007_BUF_SIZE)
1736 return -EINVAL; /* must map exactly one full buffer */
1737 down(&gofh->lock);
1738 index = vma->vm_pgoff / GO7007_BUF_PAGES;
1739 if (index >= gofh->buf_count) {
1740 up(&gofh->lock);
1741 return -EINVAL; /* trying to map beyond requested buffers */
1743 if (index * GO7007_BUF_PAGES != vma->vm_pgoff) {
1744 up(&gofh->lock);
1745 return -EINVAL; /* offset is not aligned on buffer boundary */
1747 if (gofh->bufs[index].mapped > 0) {
1748 up(&gofh->lock);
1749 return -EBUSY;
1751 gofh->bufs[index].mapped = 1;
1752 gofh->bufs[index].user_addr = vma->vm_start;
1753 vma->vm_ops = &go7007_vm_ops;
1754 vma->vm_flags |= VM_DONTEXPAND;
1755 vma->vm_flags &= ~VM_IO;
1756 vma->vm_private_data = &gofh->bufs[index];
1757 up(&gofh->lock);
1758 return 0;
1761 static unsigned int go7007_poll(struct file *file, poll_table *wait)
1763 struct go7007_file *gofh = file->private_data;
1764 struct go7007_buffer *gobuf;
1766 if (list_empty(&gofh->go->stream))
1767 return POLLERR;
1768 gobuf = list_entry(gofh->go->stream.next, struct go7007_buffer, stream);
1769 poll_wait(file, &gofh->go->frame_waitq, wait);
1770 if (gobuf->state == BUF_STATE_DONE)
1771 return POLLIN | POLLRDNORM;
1772 return 0;
1775 static void go7007_vfl_release(struct video_device *vfd)
1777 struct go7007 *go = video_get_drvdata(vfd);
1779 video_device_release(vfd);
1780 if (--go->ref_count == 0)
1781 kfree(go);
1784 static struct v4l2_file_operations go7007_fops = {
1785 .owner = THIS_MODULE,
1786 .open = go7007_open,
1787 .release = go7007_release,
1788 .ioctl = video_ioctl2,
1789 .read = go7007_read,
1790 .mmap = go7007_mmap,
1791 .poll = go7007_poll,
1794 static const struct v4l2_ioctl_ops video_ioctl_ops = {
1795 .vidioc_querycap = vidioc_querycap,
1796 .vidioc_enum_fmt_vid_cap = vidioc_enum_fmt_vid_cap,
1797 .vidioc_g_fmt_vid_cap = vidioc_g_fmt_vid_cap,
1798 .vidioc_try_fmt_vid_cap = vidioc_try_fmt_vid_cap,
1799 .vidioc_s_fmt_vid_cap = vidioc_s_fmt_vid_cap,
1800 .vidioc_reqbufs = vidioc_reqbufs,
1801 .vidioc_querybuf = vidioc_querybuf,
1802 .vidioc_qbuf = vidioc_qbuf,
1803 .vidioc_dqbuf = vidioc_dqbuf,
1804 .vidioc_s_std = vidioc_s_std,
1805 .vidioc_enum_input = vidioc_enum_input,
1806 .vidioc_g_input = vidioc_g_input,
1807 .vidioc_s_input = vidioc_s_input,
1808 .vidioc_queryctrl = vidioc_queryctrl,
1809 .vidioc_g_ctrl = vidioc_g_ctrl,
1810 .vidioc_s_ctrl = vidioc_s_ctrl,
1811 .vidioc_streamon = vidioc_streamon,
1812 .vidioc_streamoff = vidioc_streamoff,
1813 .vidioc_g_tuner = vidioc_g_tuner,
1814 .vidioc_s_tuner = vidioc_s_tuner,
1815 .vidioc_g_frequency = vidioc_g_frequency,
1816 .vidioc_s_frequency = vidioc_s_frequency,
1817 .vidioc_g_parm = vidioc_g_parm,
1818 .vidioc_s_parm = vidioc_s_parm,
1819 .vidioc_enum_framesizes = vidioc_enum_framesizes,
1820 .vidioc_enum_frameintervals = vidioc_enum_frameintervals,
1821 .vidioc_cropcap = vidioc_cropcap,
1822 .vidioc_g_crop = vidioc_g_crop,
1823 .vidioc_s_crop = vidioc_s_crop,
1824 .vidioc_g_jpegcomp = vidioc_g_jpegcomp,
1825 .vidioc_s_jpegcomp = vidioc_s_jpegcomp,
1828 static struct video_device go7007_template = {
1829 .name = "go7007",
1830 .fops = &go7007_fops,
1831 .minor = -1,
1832 .release = go7007_vfl_release,
1833 .ioctl_ops = &video_ioctl_ops,
1834 .tvnorms = V4L2_STD_ALL,
1835 .current_norm = V4L2_STD_NTSC,
1838 int go7007_v4l2_init(struct go7007 *go)
1840 int rv;
1842 go->video_dev = video_device_alloc();
1843 if (go->video_dev == NULL)
1844 return -ENOMEM;
1845 memcpy(go->video_dev, &go7007_template, sizeof(go7007_template));
1846 go->video_dev->parent = go->dev;
1847 rv = video_register_device(go->video_dev, VFL_TYPE_GRABBER, -1);
1848 if (rv < 0) {
1849 video_device_release(go->video_dev);
1850 go->video_dev = NULL;
1851 return rv;
1853 video_set_drvdata(go->video_dev, go);
1854 ++go->ref_count;
1855 printk(KERN_INFO "%s: registered device video%d [v4l2]\n",
1856 go->video_dev->name, go->video_dev->num);
1858 return 0;
1861 void go7007_v4l2_remove(struct go7007 *go)
1863 unsigned long flags;
1865 down(&go->hw_lock);
1866 if (go->streaming) {
1867 go->streaming = 0;
1868 go7007_stream_stop(go);
1869 spin_lock_irqsave(&go->spinlock, flags);
1870 abort_queued(go);
1871 spin_unlock_irqrestore(&go->spinlock, flags);
1873 up(&go->hw_lock);
1874 if (go->video_dev)
1875 video_unregister_device(go->video_dev);