Full support for Ginger Console
[linux-ginger.git] / drivers / staging / go7007 / go7007-v4l2.c
blob4bd353afa596a5ba5756af1f7d769fd74faae929
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/mutex.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 mutex_lock(&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 mutex_unlock(&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 mutex_init(&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;
386 #endif
388 static int mpeg_queryctrl(struct v4l2_queryctrl *ctrl)
390 static const u32 mpeg_ctrls[] = {
391 V4L2_CID_MPEG_CLASS,
392 V4L2_CID_MPEG_STREAM_TYPE,
393 V4L2_CID_MPEG_VIDEO_ENCODING,
394 V4L2_CID_MPEG_VIDEO_ASPECT,
395 V4L2_CID_MPEG_VIDEO_GOP_SIZE,
396 V4L2_CID_MPEG_VIDEO_GOP_CLOSURE,
397 V4L2_CID_MPEG_VIDEO_BITRATE,
400 static const u32 *ctrl_classes[] = {
401 mpeg_ctrls,
402 NULL
405 ctrl->id = v4l2_ctrl_next(ctrl_classes, ctrl->id);
407 switch (ctrl->id) {
408 case V4L2_CID_MPEG_CLASS:
409 return v4l2_ctrl_query_fill(ctrl, 0, 0, 0, 0);
410 case V4L2_CID_MPEG_STREAM_TYPE:
411 return v4l2_ctrl_query_fill(ctrl,
412 V4L2_MPEG_STREAM_TYPE_MPEG2_DVD,
413 V4L2_MPEG_STREAM_TYPE_MPEG_ELEM, 1,
414 V4L2_MPEG_STREAM_TYPE_MPEG_ELEM);
415 case V4L2_CID_MPEG_VIDEO_ENCODING:
416 return v4l2_ctrl_query_fill(ctrl,
417 V4L2_MPEG_VIDEO_ENCODING_MPEG_1,
418 V4L2_MPEG_VIDEO_ENCODING_MPEG_4, 1,
419 V4L2_MPEG_VIDEO_ENCODING_MPEG_2);
420 case V4L2_CID_MPEG_VIDEO_ASPECT:
421 return v4l2_ctrl_query_fill(ctrl,
422 V4L2_MPEG_VIDEO_ASPECT_1x1,
423 V4L2_MPEG_VIDEO_ASPECT_16x9, 1,
424 V4L2_MPEG_VIDEO_ASPECT_1x1);
425 case V4L2_CID_MPEG_VIDEO_GOP_SIZE:
426 return v4l2_ctrl_query_fill(ctrl, 0, 34, 1, 15);
427 case V4L2_CID_MPEG_VIDEO_GOP_CLOSURE:
428 return v4l2_ctrl_query_fill(ctrl, 0, 1, 1, 0);
429 case V4L2_CID_MPEG_VIDEO_BITRATE:
430 return v4l2_ctrl_query_fill(ctrl,
431 64000,
432 10000000, 1,
433 1500000);
434 default:
435 return -EINVAL;
437 return 0;
440 static int mpeg_s_ctrl(struct v4l2_control *ctrl, struct go7007 *go)
442 /* pretty sure we can't change any of these while streaming */
443 if (go->streaming)
444 return -EBUSY;
446 switch (ctrl->id) {
447 case V4L2_CID_MPEG_STREAM_TYPE:
448 switch (ctrl->value) {
449 case V4L2_MPEG_STREAM_TYPE_MPEG2_DVD:
450 go->format = GO7007_FORMAT_MPEG2;
451 go->bitrate = 9800000;
452 go->gop_size = 15;
453 go->pali = 0x48;
454 go->closed_gop = 1;
455 go->repeat_seqhead = 0;
456 go->seq_header_enable = 1;
457 go->gop_header_enable = 1;
458 go->dvd_mode = 1;
459 break;
460 case V4L2_MPEG_STREAM_TYPE_MPEG_ELEM:
461 /* todo: */
462 break;
463 default:
464 return -EINVAL;
466 break;
467 case V4L2_CID_MPEG_VIDEO_ENCODING:
468 switch (ctrl->value) {
469 case V4L2_MPEG_VIDEO_ENCODING_MPEG_1:
470 go->format = GO7007_FORMAT_MPEG1;
471 go->pali = 0;
472 break;
473 case V4L2_MPEG_VIDEO_ENCODING_MPEG_2:
474 go->format = GO7007_FORMAT_MPEG2;
475 /*if (mpeg->pali >> 24 == 2)
476 go->pali = mpeg->pali & 0xff;
477 else*/
478 go->pali = 0x48;
479 break;
480 case V4L2_MPEG_VIDEO_ENCODING_MPEG_4:
481 go->format = GO7007_FORMAT_MPEG4;
482 /*if (mpeg->pali >> 24 == 4)
483 go->pali = mpeg->pali & 0xff;
484 else*/
485 go->pali = 0xf5;
486 break;
487 default:
488 return -EINVAL;
490 go->gop_header_enable =
491 /*mpeg->flags & GO7007_MPEG_OMIT_GOP_HEADER
492 ? 0 :*/ 1;
493 /*if (mpeg->flags & GO7007_MPEG_REPEAT_SEQHEADER)
494 go->repeat_seqhead = 1;
495 else*/
496 go->repeat_seqhead = 0;
497 go->dvd_mode = 0;
498 break;
499 case V4L2_CID_MPEG_VIDEO_ASPECT:
500 if (go->format == GO7007_FORMAT_MJPEG)
501 return -EINVAL;
502 switch (ctrl->value) {
503 case V4L2_MPEG_VIDEO_ASPECT_1x1:
504 go->aspect_ratio = GO7007_RATIO_1_1;
505 break;
506 case V4L2_MPEG_VIDEO_ASPECT_4x3:
507 go->aspect_ratio = GO7007_RATIO_4_3;
508 break;
509 case V4L2_MPEG_VIDEO_ASPECT_16x9:
510 go->aspect_ratio = GO7007_RATIO_16_9;
511 break;
512 case V4L2_MPEG_VIDEO_ASPECT_221x100:
513 default:
514 return -EINVAL;
516 break;
517 case V4L2_CID_MPEG_VIDEO_GOP_SIZE:
518 if (ctrl->value < 0 || ctrl->value > 34)
519 return -EINVAL;
520 go->gop_size = ctrl->value;
521 break;
522 case V4L2_CID_MPEG_VIDEO_GOP_CLOSURE:
523 if (ctrl->value != 0 && ctrl->value != 1)
524 return -EINVAL;
525 go->closed_gop = ctrl->value;
526 break;
527 case V4L2_CID_MPEG_VIDEO_BITRATE:
528 /* Upper bound is kind of arbitrary here */
529 if (ctrl->value < 64000 || ctrl->value > 10000000)
530 return -EINVAL;
531 go->bitrate = ctrl->value;
532 break;
533 default:
534 return -EINVAL;
536 return 0;
539 static int mpeg_g_ctrl(struct v4l2_control *ctrl, struct go7007 *go)
541 switch (ctrl->id) {
542 case V4L2_CID_MPEG_STREAM_TYPE:
543 if (go->dvd_mode)
544 ctrl->value = V4L2_MPEG_STREAM_TYPE_MPEG2_DVD;
545 else
546 ctrl->value = V4L2_MPEG_STREAM_TYPE_MPEG_ELEM;
547 break;
548 case V4L2_CID_MPEG_VIDEO_ENCODING:
549 switch (go->format) {
550 case GO7007_FORMAT_MPEG1:
551 ctrl->value = V4L2_MPEG_VIDEO_ENCODING_MPEG_1;
552 break;
553 case GO7007_FORMAT_MPEG2:
554 ctrl->value = V4L2_MPEG_VIDEO_ENCODING_MPEG_2;
555 break;
556 case GO7007_FORMAT_MPEG4:
557 ctrl->value = V4L2_MPEG_VIDEO_ENCODING_MPEG_4;
558 break;
559 default:
560 return -EINVAL;
562 break;
563 case V4L2_CID_MPEG_VIDEO_ASPECT:
564 switch (go->aspect_ratio) {
565 case GO7007_RATIO_1_1:
566 ctrl->value = V4L2_MPEG_VIDEO_ASPECT_1x1;
567 break;
568 case GO7007_RATIO_4_3:
569 ctrl->value = V4L2_MPEG_VIDEO_ASPECT_4x3;
570 break;
571 case GO7007_RATIO_16_9:
572 ctrl->value = V4L2_MPEG_VIDEO_ASPECT_16x9;
573 break;
574 default:
575 return -EINVAL;
577 break;
578 case V4L2_CID_MPEG_VIDEO_GOP_SIZE:
579 ctrl->value = go->gop_size;
580 break;
581 case V4L2_CID_MPEG_VIDEO_GOP_CLOSURE:
582 ctrl->value = go->closed_gop;
583 break;
584 case V4L2_CID_MPEG_VIDEO_BITRATE:
585 ctrl->value = go->bitrate;
586 break;
587 default:
588 return -EINVAL;
590 return 0;
593 static int vidioc_querycap(struct file *file, void *priv,
594 struct v4l2_capability *cap)
596 struct go7007 *go = ((struct go7007_file *) priv)->go;
598 strlcpy(cap->driver, "go7007", sizeof(cap->driver));
599 strlcpy(cap->card, go->name, sizeof(cap->card));
600 #if 0
601 strlcpy(cap->bus_info, dev_name(&dev->udev->dev), sizeof(cap->bus_info));
602 #endif
604 cap->version = KERNEL_VERSION(0, 9, 8);
606 cap->capabilities = V4L2_CAP_VIDEO_CAPTURE |
607 V4L2_CAP_STREAMING; /* | V4L2_CAP_AUDIO; */
609 if (go->board_info->flags & GO7007_BOARD_HAS_TUNER)
610 cap->capabilities |= V4L2_CAP_TUNER;
612 return 0;
615 static int vidioc_enum_fmt_vid_cap(struct file *file, void *priv,
616 struct v4l2_fmtdesc *fmt)
618 char *desc = NULL;
620 switch (fmt->index) {
621 case 0:
622 fmt->pixelformat = V4L2_PIX_FMT_MJPEG;
623 desc = "Motion-JPEG";
624 break;
625 case 1:
626 fmt->pixelformat = V4L2_PIX_FMT_MPEG;
627 desc = "MPEG1/MPEG2/MPEG4";
628 break;
629 default:
630 return -EINVAL;
632 fmt->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
633 fmt->flags = V4L2_FMT_FLAG_COMPRESSED;
635 strncpy(fmt->description, desc, sizeof(fmt->description));
637 return 0;
640 static int vidioc_g_fmt_vid_cap(struct file *file, void *priv,
641 struct v4l2_format *fmt)
643 struct go7007 *go = ((struct go7007_file *) priv)->go;
645 fmt->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
646 fmt->fmt.pix.width = go->width;
647 fmt->fmt.pix.height = go->height;
648 fmt->fmt.pix.pixelformat = (go->format == GO7007_FORMAT_MJPEG) ?
649 V4L2_PIX_FMT_MJPEG : V4L2_PIX_FMT_MPEG;
650 fmt->fmt.pix.field = V4L2_FIELD_NONE;
651 fmt->fmt.pix.bytesperline = 0;
652 fmt->fmt.pix.sizeimage = GO7007_BUF_SIZE;
653 fmt->fmt.pix.colorspace = V4L2_COLORSPACE_SMPTE170M;
655 return 0;
658 static int vidioc_try_fmt_vid_cap(struct file *file, void *priv,
659 struct v4l2_format *fmt)
661 struct go7007 *go = ((struct go7007_file *) priv)->go;
663 return set_capture_size(go, fmt, 1);
666 static int vidioc_s_fmt_vid_cap(struct file *file, void *priv,
667 struct v4l2_format *fmt)
669 struct go7007 *go = ((struct go7007_file *) priv)->go;
671 if (go->streaming)
672 return -EBUSY;
674 return set_capture_size(go, fmt, 0);
677 static int vidioc_reqbufs(struct file *file, void *priv,
678 struct v4l2_requestbuffers *req)
680 struct go7007_file *gofh = priv;
681 struct go7007 *go = gofh->go;
682 int retval = -EBUSY;
683 unsigned int count, i;
685 if (go->streaming)
686 return retval;
688 if (req->type != V4L2_BUF_TYPE_VIDEO_CAPTURE ||
689 req->memory != V4L2_MEMORY_MMAP)
690 return -EINVAL;
692 mutex_lock(&gofh->lock);
693 for (i = 0; i < gofh->buf_count; ++i)
694 if (gofh->bufs[i].mapped > 0)
695 goto unlock_and_return;
697 mutex_lock(&go->hw_lock);
698 if (go->in_use > 0 && gofh->buf_count == 0) {
699 mutex_unlock(&go->hw_lock);
700 goto unlock_and_return;
703 if (gofh->buf_count > 0)
704 kfree(gofh->bufs);
706 retval = -ENOMEM;
707 count = req->count;
708 if (count > 0) {
709 if (count < 2)
710 count = 2;
711 if (count > 32)
712 count = 32;
714 gofh->bufs = kmalloc(count * sizeof(struct go7007_buffer),
715 GFP_KERNEL);
717 if (!gofh->bufs) {
718 mutex_unlock(&go->hw_lock);
719 goto unlock_and_return;
722 memset(gofh->bufs, 0, count * sizeof(struct go7007_buffer));
724 for (i = 0; i < count; ++i) {
725 gofh->bufs[i].go = go;
726 gofh->bufs[i].index = i;
727 gofh->bufs[i].state = BUF_STATE_IDLE;
728 gofh->bufs[i].mapped = 0;
731 go->in_use = 1;
732 } else {
733 go->in_use = 0;
736 gofh->buf_count = count;
737 mutex_unlock(&go->hw_lock);
738 mutex_unlock(&gofh->lock);
740 memset(req, 0, sizeof(*req));
742 req->count = count;
743 req->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
744 req->memory = V4L2_MEMORY_MMAP;
746 return 0;
748 unlock_and_return:
749 mutex_unlock(&gofh->lock);
750 return retval;
753 static int vidioc_querybuf(struct file *file, void *priv,
754 struct v4l2_buffer *buf)
756 struct go7007_file *gofh = priv;
757 int retval = -EINVAL;
758 unsigned int index;
760 if (buf->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
761 return retval;
763 index = buf->index;
765 mutex_lock(&gofh->lock);
766 if (index >= gofh->buf_count)
767 goto unlock_and_return;
769 memset(buf, 0, sizeof(*buf));
770 buf->index = index;
771 buf->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
773 switch (gofh->bufs[index].state) {
774 case BUF_STATE_QUEUED:
775 buf->flags = V4L2_BUF_FLAG_QUEUED;
776 break;
777 case BUF_STATE_DONE:
778 buf->flags = V4L2_BUF_FLAG_DONE;
779 break;
780 default:
781 buf->flags = 0;
784 if (gofh->bufs[index].mapped)
785 buf->flags |= V4L2_BUF_FLAG_MAPPED;
786 buf->memory = V4L2_MEMORY_MMAP;
787 buf->m.offset = index * GO7007_BUF_SIZE;
788 buf->length = GO7007_BUF_SIZE;
789 mutex_unlock(&gofh->lock);
791 return 0;
793 unlock_and_return:
794 mutex_unlock(&gofh->lock);
795 return retval;
798 static int vidioc_qbuf(struct file *file, void *priv, struct v4l2_buffer *buf)
800 struct go7007_file *gofh = priv;
801 struct go7007 *go = gofh->go;
802 struct go7007_buffer *gobuf;
803 unsigned long flags;
804 int retval = -EINVAL;
805 int ret;
807 if (buf->type != V4L2_BUF_TYPE_VIDEO_CAPTURE ||
808 buf->memory != V4L2_MEMORY_MMAP)
809 return retval;
811 mutex_lock(&gofh->lock);
812 if (buf->index < 0 || buf->index >= gofh->buf_count)
813 goto unlock_and_return;
815 gobuf = &gofh->bufs[buf->index];
816 if (!gobuf->mapped)
817 goto unlock_and_return;
819 retval = -EBUSY;
820 if (gobuf->state != BUF_STATE_IDLE)
821 goto unlock_and_return;
823 /* offset will be 0 until we really support USERPTR streaming */
824 gobuf->offset = gobuf->user_addr & ~PAGE_MASK;
825 gobuf->bytesused = 0;
826 gobuf->frame_offset = 0;
827 gobuf->modet_active = 0;
828 if (gobuf->offset > 0)
829 gobuf->page_count = GO7007_BUF_PAGES + 1;
830 else
831 gobuf->page_count = GO7007_BUF_PAGES;
833 retval = -ENOMEM;
834 down_read(&current->mm->mmap_sem);
835 ret = get_user_pages(current, current->mm,
836 gobuf->user_addr & PAGE_MASK, gobuf->page_count,
837 1, 1, gobuf->pages, NULL);
838 up_read(&current->mm->mmap_sem);
840 if (ret != gobuf->page_count) {
841 int i;
842 for (i = 0; i < ret; ++i)
843 page_cache_release(gobuf->pages[i]);
844 gobuf->page_count = 0;
845 goto unlock_and_return;
848 gobuf->state = BUF_STATE_QUEUED;
849 spin_lock_irqsave(&go->spinlock, flags);
850 list_add_tail(&gobuf->stream, &go->stream);
851 spin_unlock_irqrestore(&go->spinlock, flags);
852 mutex_unlock(&gofh->lock);
854 return 0;
856 unlock_and_return:
857 mutex_unlock(&gofh->lock);
858 return retval;
862 static int vidioc_dqbuf(struct file *file, void *priv, struct v4l2_buffer *buf)
864 struct go7007_file *gofh = priv;
865 struct go7007 *go = gofh->go;
866 struct go7007_buffer *gobuf;
867 int retval = -EINVAL;
868 unsigned long flags;
869 u32 frame_type_flag;
870 DEFINE_WAIT(wait);
872 if (buf->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
873 return retval;
874 if (buf->memory != V4L2_MEMORY_MMAP)
875 return retval;
877 mutex_lock(&gofh->lock);
878 if (list_empty(&go->stream))
879 goto unlock_and_return;
880 gobuf = list_entry(go->stream.next,
881 struct go7007_buffer, stream);
883 retval = -EAGAIN;
884 if (gobuf->state != BUF_STATE_DONE &&
885 !(file->f_flags & O_NONBLOCK)) {
886 for (;;) {
887 prepare_to_wait(&go->frame_waitq, &wait,
888 TASK_INTERRUPTIBLE);
889 if (gobuf->state == BUF_STATE_DONE)
890 break;
891 if (signal_pending(current)) {
892 retval = -ERESTARTSYS;
893 break;
895 schedule();
897 finish_wait(&go->frame_waitq, &wait);
899 if (gobuf->state != BUF_STATE_DONE)
900 goto unlock_and_return;
902 spin_lock_irqsave(&go->spinlock, flags);
903 deactivate_buffer(gobuf);
904 spin_unlock_irqrestore(&go->spinlock, flags);
905 frame_type_flag = get_frame_type_flag(gobuf, go->format);
906 gobuf->state = BUF_STATE_IDLE;
908 memset(buf, 0, sizeof(*buf));
909 buf->index = gobuf->index;
910 buf->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
911 buf->bytesused = gobuf->bytesused;
912 buf->flags = V4L2_BUF_FLAG_MAPPED | frame_type_flag;
913 buf->field = V4L2_FIELD_NONE;
914 buf->timestamp = gobuf->timestamp;
915 buf->sequence = gobuf->seq;
916 buf->memory = V4L2_MEMORY_MMAP;
917 buf->m.offset = gobuf->index * GO7007_BUF_SIZE;
918 buf->length = GO7007_BUF_SIZE;
919 buf->reserved = gobuf->modet_active;
921 mutex_unlock(&gofh->lock);
922 return 0;
924 unlock_and_return:
925 mutex_unlock(&gofh->lock);
926 return retval;
929 static int vidioc_streamon(struct file *file, void *priv,
930 enum v4l2_buf_type type)
932 struct go7007_file *gofh = priv;
933 struct go7007 *go = gofh->go;
934 int retval = 0;
936 if (type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
937 return -EINVAL;
939 mutex_lock(&gofh->lock);
940 mutex_lock(&go->hw_lock);
942 if (!go->streaming) {
943 go->streaming = 1;
944 go->next_seq = 0;
945 go->active_buf = NULL;
946 if (go7007_start_encoder(go) < 0)
947 retval = -EIO;
948 else
949 retval = 0;
951 mutex_unlock(&go->hw_lock);
952 mutex_unlock(&gofh->lock);
954 return retval;
957 static int vidioc_streamoff(struct file *file, void *priv,
958 enum v4l2_buf_type type)
960 struct go7007_file *gofh = priv;
961 struct go7007 *go = gofh->go;
963 if (type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
964 return -EINVAL;
965 mutex_lock(&gofh->lock);
966 go7007_streamoff(go);
967 mutex_unlock(&gofh->lock);
969 return 0;
972 static int vidioc_queryctrl(struct file *file, void *priv,
973 struct v4l2_queryctrl *query)
975 struct go7007 *go = ((struct go7007_file *) priv)->go;
977 if (!go->i2c_adapter_online)
978 return -EIO;
980 i2c_clients_command(&go->i2c_adapter, VIDIOC_QUERYCTRL, query);
982 return (!query->name[0]) ? mpeg_queryctrl(query) : 0;
985 static int vidioc_g_ctrl(struct file *file, void *priv,
986 struct v4l2_control *ctrl)
988 struct go7007 *go = ((struct go7007_file *) priv)->go;
989 struct v4l2_queryctrl query;
991 if (!go->i2c_adapter_online)
992 return -EIO;
994 memset(&query, 0, sizeof(query));
995 query.id = ctrl->id;
996 i2c_clients_command(&go->i2c_adapter, VIDIOC_QUERYCTRL, &query);
997 if (query.name[0] == 0)
998 return mpeg_g_ctrl(ctrl, go);
999 i2c_clients_command(&go->i2c_adapter, VIDIOC_G_CTRL, ctrl);
1001 return 0;
1004 static int vidioc_s_ctrl(struct file *file, void *priv,
1005 struct v4l2_control *ctrl)
1007 struct go7007 *go = ((struct go7007_file *) priv)->go;
1008 struct v4l2_queryctrl query;
1010 if (!go->i2c_adapter_online)
1011 return -EIO;
1013 memset(&query, 0, sizeof(query));
1014 query.id = ctrl->id;
1015 i2c_clients_command(&go->i2c_adapter, VIDIOC_QUERYCTRL, &query);
1016 if (query.name[0] == 0)
1017 return mpeg_s_ctrl(ctrl, go);
1018 i2c_clients_command(&go->i2c_adapter, VIDIOC_S_CTRL, ctrl);
1020 return 0;
1023 static int vidioc_g_parm(struct file *filp, void *priv,
1024 struct v4l2_streamparm *parm)
1026 struct go7007 *go = ((struct go7007_file *) priv)->go;
1027 struct v4l2_fract timeperframe = {
1028 .numerator = 1001 * go->fps_scale,
1029 .denominator = go->sensor_framerate,
1032 if (parm->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
1033 return -EINVAL;
1035 parm->parm.capture.capability |= V4L2_CAP_TIMEPERFRAME;
1036 parm->parm.capture.timeperframe = timeperframe;
1038 return 0;
1041 static int vidioc_s_parm(struct file *filp, void *priv,
1042 struct v4l2_streamparm *parm)
1044 struct go7007 *go = ((struct go7007_file *) priv)->go;
1045 unsigned int n, d;
1047 if (parm->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
1048 return -EINVAL;
1049 if (parm->parm.capture.capturemode != 0)
1050 return -EINVAL;
1052 n = go->sensor_framerate *
1053 parm->parm.capture.timeperframe.numerator;
1054 d = 1001 * parm->parm.capture.timeperframe.denominator;
1055 if (n != 0 && d != 0 && n > d)
1056 go->fps_scale = (n + d/2) / d;
1057 else
1058 go->fps_scale = 1;
1060 return 0;
1063 /* VIDIOC_ENUMSTD on go7007 were used for enumberating the supported fps and
1064 its resolution, when the device is not connected to TV.
1065 This were an API abuse, probably used by the lack of specific IOCTL's to
1066 enumberate it, by the time the driver were written.
1068 However, since kernel 2.6.19, two new ioctls (VIDIOC_ENUM_FRAMEINTERVALS
1069 and VIDIOC_ENUM_FRAMESIZES) were added for this purpose.
1071 The two functions bellow implements the newer ioctls
1073 static int vidioc_enum_framesizes(struct file *filp, void *priv,
1074 struct v4l2_frmsizeenum *fsize)
1076 struct go7007 *go = ((struct go7007_file *) priv)->go;
1078 /* Return -EINVAL, if it is a TV board */
1079 if ((go->board_info->flags & GO7007_BOARD_HAS_TUNER) ||
1080 (go->board_info->sensor_flags & GO7007_SENSOR_TV))
1081 return -EINVAL;
1083 if (fsize->index > 0)
1084 return -EINVAL;
1086 fsize->type = V4L2_FRMSIZE_TYPE_DISCRETE;
1087 fsize->discrete.width = go->board_info->sensor_width;
1088 fsize->discrete.height = go->board_info->sensor_height;
1090 return 0;
1093 static int vidioc_enum_frameintervals(struct file *filp, void *priv,
1094 struct v4l2_frmivalenum *fival)
1096 struct go7007 *go = ((struct go7007_file *) priv)->go;
1098 /* Return -EINVAL, if it is a TV board */
1099 if ((go->board_info->flags & GO7007_BOARD_HAS_TUNER) ||
1100 (go->board_info->sensor_flags & GO7007_SENSOR_TV))
1101 return -EINVAL;
1103 if (fival->index > 0)
1104 return -EINVAL;
1106 fival->type = V4L2_FRMIVAL_TYPE_DISCRETE;
1107 fival->discrete.numerator = 1001;
1108 fival->discrete.denominator = go->board_info->sensor_framerate;
1110 return 0;
1113 static int vidioc_g_std(struct file *file, void *priv, v4l2_std_id *std)
1115 struct go7007 *go = ((struct go7007_file *) priv)->go;
1117 switch (go->standard) {
1118 case GO7007_STD_NTSC:
1119 *std = V4L2_STD_NTSC;
1120 break;
1121 case GO7007_STD_PAL:
1122 *std = V4L2_STD_PAL;
1123 break;
1124 default:
1125 return -EINVAL;
1128 return 0;
1131 static int vidioc_s_std(struct file *file, void *priv, v4l2_std_id *std)
1133 struct go7007 *go = ((struct go7007_file *) priv)->go;
1135 if (go->streaming)
1136 return -EBUSY;
1138 if (!(go->board_info->sensor_flags & GO7007_SENSOR_TV) &&
1139 *std != 0)
1140 return -EINVAL;
1142 if (*std == 0)
1143 return -EINVAL;
1145 if ((go->board_info->flags & GO7007_BOARD_HAS_TUNER) &&
1146 go->input == go->board_info->num_inputs - 1) {
1147 if (!go->i2c_adapter_online)
1148 return -EIO;
1149 i2c_clients_command(&go->i2c_adapter,
1150 VIDIOC_S_STD, std);
1151 if (!*std) /* hack to indicate EINVAL from tuner */
1152 return -EINVAL;
1155 if (*std & V4L2_STD_NTSC) {
1156 go->standard = GO7007_STD_NTSC;
1157 go->sensor_framerate = 30000;
1158 } else if (*std & V4L2_STD_PAL) {
1159 go->standard = GO7007_STD_PAL;
1160 go->sensor_framerate = 25025;
1161 } else if (*std & V4L2_STD_SECAM) {
1162 go->standard = GO7007_STD_PAL;
1163 go->sensor_framerate = 25025;
1164 } else
1165 return -EINVAL;
1167 if (go->i2c_adapter_online)
1168 i2c_clients_command(&go->i2c_adapter,
1169 VIDIOC_S_STD, std);
1170 set_capture_size(go, NULL, 0);
1172 return 0;
1175 static int vidioc_querystd(struct file *file, void *priv, v4l2_std_id *std)
1177 struct go7007 *go = ((struct go7007_file *) priv)->go;
1179 if ((go->board_info->flags & GO7007_BOARD_HAS_TUNER) &&
1180 go->input == go->board_info->num_inputs - 1) {
1181 if (!go->i2c_adapter_online)
1182 return -EIO;
1183 i2c_clients_command(&go->i2c_adapter, VIDIOC_QUERYSTD, std);
1184 } else if (go->board_info->sensor_flags & GO7007_SENSOR_TV)
1185 *std = V4L2_STD_NTSC | V4L2_STD_PAL | V4L2_STD_SECAM;
1186 else
1187 *std = 0;
1189 return 0;
1192 static int vidioc_enum_input(struct file *file, void *priv,
1193 struct v4l2_input *inp)
1195 struct go7007 *go = ((struct go7007_file *) priv)->go;
1197 if (inp->index >= go->board_info->num_inputs)
1198 return -EINVAL;
1200 strncpy(inp->name, go->board_info->inputs[inp->index].name,
1201 sizeof(inp->name));
1203 /* If this board has a tuner, it will be the last input */
1204 if ((go->board_info->flags & GO7007_BOARD_HAS_TUNER) &&
1205 inp->index == go->board_info->num_inputs - 1)
1206 inp->type = V4L2_INPUT_TYPE_TUNER;
1207 else
1208 inp->type = V4L2_INPUT_TYPE_CAMERA;
1210 inp->audioset = 0;
1211 inp->tuner = 0;
1212 if (go->board_info->sensor_flags & GO7007_SENSOR_TV)
1213 inp->std = V4L2_STD_NTSC | V4L2_STD_PAL |
1214 V4L2_STD_SECAM;
1215 else
1216 inp->std = 0;
1218 return 0;
1222 static int vidioc_g_input(struct file *file, void *priv, unsigned int *input)
1224 struct go7007 *go = ((struct go7007_file *) priv)->go;
1226 *input = go->input;
1228 return 0;
1231 static int vidioc_s_input(struct file *file, void *priv, unsigned int input)
1233 struct go7007 *go = ((struct go7007_file *) priv)->go;
1235 if (input >= go->board_info->num_inputs)
1236 return -EINVAL;
1237 if (go->streaming)
1238 return -EBUSY;
1240 go->input = input;
1241 if (go->i2c_adapter_online) {
1242 i2c_clients_command(&go->i2c_adapter, VIDIOC_S_INPUT,
1243 &go->board_info->inputs[input].video_input);
1244 i2c_clients_command(&go->i2c_adapter, VIDIOC_S_AUDIO,
1245 &go->board_info->inputs[input].audio_input);
1248 return 0;
1251 static int vidioc_g_tuner(struct file *file, void *priv,
1252 struct v4l2_tuner *t)
1254 struct go7007 *go = ((struct go7007_file *) priv)->go;
1256 if (!(go->board_info->flags & GO7007_BOARD_HAS_TUNER))
1257 return -EINVAL;
1258 if (t->index != 0)
1259 return -EINVAL;
1260 if (!go->i2c_adapter_online)
1261 return -EIO;
1263 i2c_clients_command(&go->i2c_adapter, VIDIOC_G_TUNER, t);
1265 t->index = 0;
1266 return 0;
1269 static int vidioc_s_tuner(struct file *file, void *priv,
1270 struct v4l2_tuner *t)
1272 struct go7007 *go = ((struct go7007_file *) priv)->go;
1274 if (!(go->board_info->flags & GO7007_BOARD_HAS_TUNER))
1275 return -EINVAL;
1276 if (t->index != 0)
1277 return -EINVAL;
1278 if (!go->i2c_adapter_online)
1279 return -EIO;
1281 switch (go->board_id) {
1282 case GO7007_BOARDID_PX_TV402U_NA:
1283 case GO7007_BOARDID_PX_TV402U_JP:
1284 /* No selectable options currently */
1285 if (t->audmode != V4L2_TUNER_MODE_STEREO)
1286 return -EINVAL;
1287 break;
1290 i2c_clients_command(&go->i2c_adapter, VIDIOC_S_TUNER, t);
1292 return 0;
1295 static int vidioc_g_frequency(struct file *file, void *priv,
1296 struct v4l2_frequency *f)
1298 struct go7007 *go = ((struct go7007_file *) priv)->go;
1300 if (!(go->board_info->flags & GO7007_BOARD_HAS_TUNER))
1301 return -EINVAL;
1302 if (!go->i2c_adapter_online)
1303 return -EIO;
1305 f->type = V4L2_TUNER_ANALOG_TV;
1306 i2c_clients_command(&go->i2c_adapter, VIDIOC_G_FREQUENCY, f);
1307 return 0;
1310 static int vidioc_s_frequency(struct file *file, void *priv,
1311 struct v4l2_frequency *f)
1313 struct go7007 *go = ((struct go7007_file *) priv)->go;
1315 if (!(go->board_info->flags & GO7007_BOARD_HAS_TUNER))
1316 return -EINVAL;
1317 if (!go->i2c_adapter_online)
1318 return -EIO;
1320 i2c_clients_command(&go->i2c_adapter, VIDIOC_S_FREQUENCY, f);
1322 return 0;
1325 static int vidioc_cropcap(struct file *file, void *priv,
1326 struct v4l2_cropcap *cropcap)
1328 struct go7007 *go = ((struct go7007_file *) priv)->go;
1330 if (cropcap->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
1331 return -EINVAL;
1333 /* These specify the raw input of the sensor */
1334 switch (go->standard) {
1335 case GO7007_STD_NTSC:
1336 cropcap->bounds.top = 0;
1337 cropcap->bounds.left = 0;
1338 cropcap->bounds.width = 720;
1339 cropcap->bounds.height = 480;
1340 cropcap->defrect.top = 0;
1341 cropcap->defrect.left = 0;
1342 cropcap->defrect.width = 720;
1343 cropcap->defrect.height = 480;
1344 break;
1345 case GO7007_STD_PAL:
1346 cropcap->bounds.top = 0;
1347 cropcap->bounds.left = 0;
1348 cropcap->bounds.width = 720;
1349 cropcap->bounds.height = 576;
1350 cropcap->defrect.top = 0;
1351 cropcap->defrect.left = 0;
1352 cropcap->defrect.width = 720;
1353 cropcap->defrect.height = 576;
1354 break;
1355 case GO7007_STD_OTHER:
1356 cropcap->bounds.top = 0;
1357 cropcap->bounds.left = 0;
1358 cropcap->bounds.width = go->board_info->sensor_width;
1359 cropcap->bounds.height = go->board_info->sensor_height;
1360 cropcap->defrect.top = 0;
1361 cropcap->defrect.left = 0;
1362 cropcap->defrect.width = go->board_info->sensor_width;
1363 cropcap->defrect.height = go->board_info->sensor_height;
1364 break;
1367 return 0;
1370 static int vidioc_g_crop(struct file *file, void *priv, struct v4l2_crop *crop)
1372 struct go7007 *go = ((struct go7007_file *) priv)->go;
1374 if (crop->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
1375 return -EINVAL;
1377 crop->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
1379 /* These specify the raw input of the sensor */
1380 switch (go->standard) {
1381 case GO7007_STD_NTSC:
1382 crop->c.top = 0;
1383 crop->c.left = 0;
1384 crop->c.width = 720;
1385 crop->c.height = 480;
1386 break;
1387 case GO7007_STD_PAL:
1388 crop->c.top = 0;
1389 crop->c.left = 0;
1390 crop->c.width = 720;
1391 crop->c.height = 576;
1392 break;
1393 case GO7007_STD_OTHER:
1394 crop->c.top = 0;
1395 crop->c.left = 0;
1396 crop->c.width = go->board_info->sensor_width;
1397 crop->c.height = go->board_info->sensor_height;
1398 break;
1401 return 0;
1404 /* FIXME: vidioc_s_crop is not really implemented!!!
1406 static int vidioc_s_crop(struct file *file, void *priv, struct v4l2_crop *crop)
1408 if (crop->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
1409 return -EINVAL;
1411 return 0;
1414 static int vidioc_g_jpegcomp(struct file *file, void *priv,
1415 struct v4l2_jpegcompression *params)
1417 memset(params, 0, sizeof(*params));
1418 params->quality = 50; /* ?? */
1419 params->jpeg_markers = V4L2_JPEG_MARKER_DHT |
1420 V4L2_JPEG_MARKER_DQT;
1422 return 0;
1425 static int vidioc_s_jpegcomp(struct file *file, void *priv,
1426 struct v4l2_jpegcompression *params)
1428 if (params->quality != 50 ||
1429 params->jpeg_markers != (V4L2_JPEG_MARKER_DHT |
1430 V4L2_JPEG_MARKER_DQT))
1431 return -EINVAL;
1433 return 0;
1436 /* FIXME:
1437 Those ioctls are private, and not needed, since several standard
1438 extended controls already provide streaming control.
1439 So, those ioctls should be converted into vidioc_g_ext_ctrls()
1440 and vidioc_s_ext_ctrls()
1443 #if 0
1444 /* Temporary ioctls for controlling compression characteristics */
1445 case GO7007IOC_S_BITRATE:
1447 int *bitrate = arg;
1449 if (go->streaming)
1450 return -EINVAL;
1451 /* Upper bound is kind of arbitrary here */
1452 if (*bitrate < 64000 || *bitrate > 10000000)
1453 return -EINVAL;
1454 go->bitrate = *bitrate;
1455 return 0;
1457 case GO7007IOC_G_BITRATE:
1459 int *bitrate = arg;
1461 *bitrate = go->bitrate;
1462 return 0;
1464 case GO7007IOC_S_COMP_PARAMS:
1466 struct go7007_comp_params *comp = arg;
1468 if (go->format == GO7007_FORMAT_MJPEG)
1469 return -EINVAL;
1470 if (comp->gop_size > 0)
1471 go->gop_size = comp->gop_size;
1472 else
1473 go->gop_size = go->sensor_framerate / 1000;
1474 if (go->gop_size != 15)
1475 go->dvd_mode = 0;
1476 /*go->ipb = comp->max_b_frames > 0;*/ /* completely untested */
1477 if (go->board_info->sensor_flags & GO7007_SENSOR_TV) {
1478 switch (comp->aspect_ratio) {
1479 case GO7007_ASPECT_RATIO_4_3_NTSC:
1480 case GO7007_ASPECT_RATIO_4_3_PAL:
1481 go->aspect_ratio = GO7007_RATIO_4_3;
1482 break;
1483 case GO7007_ASPECT_RATIO_16_9_NTSC:
1484 case GO7007_ASPECT_RATIO_16_9_PAL:
1485 go->aspect_ratio = GO7007_RATIO_16_9;
1486 break;
1487 default:
1488 go->aspect_ratio = GO7007_RATIO_1_1;
1489 break;
1492 if (comp->flags & GO7007_COMP_OMIT_SEQ_HEADER) {
1493 go->dvd_mode = 0;
1494 go->seq_header_enable = 0;
1495 } else {
1496 go->seq_header_enable = 1;
1498 /* fall-through */
1500 case GO7007IOC_G_COMP_PARAMS:
1502 struct go7007_comp_params *comp = arg;
1504 if (go->format == GO7007_FORMAT_MJPEG)
1505 return -EINVAL;
1506 memset(comp, 0, sizeof(*comp));
1507 comp->gop_size = go->gop_size;
1508 comp->max_b_frames = go->ipb ? 2 : 0;
1509 switch (go->aspect_ratio) {
1510 case GO7007_RATIO_4_3:
1511 if (go->standard == GO7007_STD_NTSC)
1512 comp->aspect_ratio =
1513 GO7007_ASPECT_RATIO_4_3_NTSC;
1514 else
1515 comp->aspect_ratio =
1516 GO7007_ASPECT_RATIO_4_3_PAL;
1517 break;
1518 case GO7007_RATIO_16_9:
1519 if (go->standard == GO7007_STD_NTSC)
1520 comp->aspect_ratio =
1521 GO7007_ASPECT_RATIO_16_9_NTSC;
1522 else
1523 comp->aspect_ratio =
1524 GO7007_ASPECT_RATIO_16_9_PAL;
1525 break;
1526 default:
1527 comp->aspect_ratio = GO7007_ASPECT_RATIO_1_1;
1528 break;
1530 if (go->closed_gop)
1531 comp->flags |= GO7007_COMP_CLOSED_GOP;
1532 if (!go->seq_header_enable)
1533 comp->flags |= GO7007_COMP_OMIT_SEQ_HEADER;
1534 return 0;
1536 case GO7007IOC_S_MPEG_PARAMS:
1538 struct go7007_mpeg_params *mpeg = arg;
1540 if (go->format != GO7007_FORMAT_MPEG1 &&
1541 go->format != GO7007_FORMAT_MPEG2 &&
1542 go->format != GO7007_FORMAT_MPEG4)
1543 return -EINVAL;
1545 if (mpeg->flags & GO7007_MPEG_FORCE_DVD_MODE) {
1546 go->format = GO7007_FORMAT_MPEG2;
1547 go->bitrate = 9800000;
1548 go->gop_size = 15;
1549 go->pali = 0x48;
1550 go->closed_gop = 1;
1551 go->repeat_seqhead = 0;
1552 go->seq_header_enable = 1;
1553 go->gop_header_enable = 1;
1554 go->dvd_mode = 1;
1555 } else {
1556 switch (mpeg->mpeg_video_standard) {
1557 case GO7007_MPEG_VIDEO_MPEG1:
1558 go->format = GO7007_FORMAT_MPEG1;
1559 go->pali = 0;
1560 break;
1561 case GO7007_MPEG_VIDEO_MPEG2:
1562 go->format = GO7007_FORMAT_MPEG2;
1563 if (mpeg->pali >> 24 == 2)
1564 go->pali = mpeg->pali & 0xff;
1565 else
1566 go->pali = 0x48;
1567 break;
1568 case GO7007_MPEG_VIDEO_MPEG4:
1569 go->format = GO7007_FORMAT_MPEG4;
1570 if (mpeg->pali >> 24 == 4)
1571 go->pali = mpeg->pali & 0xff;
1572 else
1573 go->pali = 0xf5;
1574 break;
1575 default:
1576 return -EINVAL;
1578 go->gop_header_enable =
1579 mpeg->flags & GO7007_MPEG_OMIT_GOP_HEADER
1580 ? 0 : 1;
1581 if (mpeg->flags & GO7007_MPEG_REPEAT_SEQHEADER)
1582 go->repeat_seqhead = 1;
1583 else
1584 go->repeat_seqhead = 0;
1585 go->dvd_mode = 0;
1587 /* fall-through */
1589 case GO7007IOC_G_MPEG_PARAMS:
1591 struct go7007_mpeg_params *mpeg = arg;
1593 memset(mpeg, 0, sizeof(*mpeg));
1594 switch (go->format) {
1595 case GO7007_FORMAT_MPEG1:
1596 mpeg->mpeg_video_standard = GO7007_MPEG_VIDEO_MPEG1;
1597 mpeg->pali = 0;
1598 break;
1599 case GO7007_FORMAT_MPEG2:
1600 mpeg->mpeg_video_standard = GO7007_MPEG_VIDEO_MPEG2;
1601 mpeg->pali = GO7007_MPEG_PROFILE(2, go->pali);
1602 break;
1603 case GO7007_FORMAT_MPEG4:
1604 mpeg->mpeg_video_standard = GO7007_MPEG_VIDEO_MPEG4;
1605 mpeg->pali = GO7007_MPEG_PROFILE(4, go->pali);
1606 break;
1607 default:
1608 return -EINVAL;
1610 if (!go->gop_header_enable)
1611 mpeg->flags |= GO7007_MPEG_OMIT_GOP_HEADER;
1612 if (go->repeat_seqhead)
1613 mpeg->flags |= GO7007_MPEG_REPEAT_SEQHEADER;
1614 if (go->dvd_mode)
1615 mpeg->flags |= GO7007_MPEG_FORCE_DVD_MODE;
1616 return 0;
1618 case GO7007IOC_S_MD_PARAMS:
1620 struct go7007_md_params *mdp = arg;
1622 if (mdp->region > 3)
1623 return -EINVAL;
1624 if (mdp->trigger > 0) {
1625 go->modet[mdp->region].pixel_threshold =
1626 mdp->pixel_threshold >> 1;
1627 go->modet[mdp->region].motion_threshold =
1628 mdp->motion_threshold >> 1;
1629 go->modet[mdp->region].mb_threshold =
1630 mdp->trigger >> 1;
1631 go->modet[mdp->region].enable = 1;
1632 } else
1633 go->modet[mdp->region].enable = 0;
1634 /* fall-through */
1636 case GO7007IOC_G_MD_PARAMS:
1638 struct go7007_md_params *mdp = arg;
1639 int region = mdp->region;
1641 if (mdp->region > 3)
1642 return -EINVAL;
1643 memset(mdp, 0, sizeof(struct go7007_md_params));
1644 mdp->region = region;
1645 if (!go->modet[region].enable)
1646 return 0;
1647 mdp->pixel_threshold =
1648 (go->modet[region].pixel_threshold << 1) + 1;
1649 mdp->motion_threshold =
1650 (go->modet[region].motion_threshold << 1) + 1;
1651 mdp->trigger =
1652 (go->modet[region].mb_threshold << 1) + 1;
1653 return 0;
1655 case GO7007IOC_S_MD_REGION:
1657 struct go7007_md_region *region = arg;
1659 if (region->region < 1 || region->region > 3)
1660 return -EINVAL;
1661 return clip_to_modet_map(go, region->region, region->clips);
1663 #endif
1665 static ssize_t go7007_read(struct file *file, char __user *data,
1666 size_t count, loff_t *ppos)
1668 return -EINVAL;
1671 static void go7007_vm_open(struct vm_area_struct *vma)
1673 struct go7007_buffer *gobuf = vma->vm_private_data;
1675 ++gobuf->mapped;
1678 static void go7007_vm_close(struct vm_area_struct *vma)
1680 struct go7007_buffer *gobuf = vma->vm_private_data;
1681 unsigned long flags;
1683 if (--gobuf->mapped == 0) {
1684 spin_lock_irqsave(&gobuf->go->spinlock, flags);
1685 deactivate_buffer(gobuf);
1686 spin_unlock_irqrestore(&gobuf->go->spinlock, flags);
1690 /* Copied from videobuf-dma-sg.c */
1691 static int go7007_vm_fault(struct vm_area_struct *vma, struct vm_fault *vmf)
1693 struct page *page;
1695 page = alloc_page(GFP_USER | __GFP_DMA32);
1696 if (!page)
1697 return VM_FAULT_OOM;
1698 clear_user_highpage(page, (unsigned long)vmf->virtual_address);
1699 vmf->page = page;
1700 return 0;
1703 static struct vm_operations_struct go7007_vm_ops = {
1704 .open = go7007_vm_open,
1705 .close = go7007_vm_close,
1706 .fault = go7007_vm_fault,
1709 static int go7007_mmap(struct file *file, struct vm_area_struct *vma)
1711 struct go7007_file *gofh = file->private_data;
1712 unsigned int index;
1714 if (gofh->go->status != STATUS_ONLINE)
1715 return -EIO;
1716 if (!(vma->vm_flags & VM_SHARED))
1717 return -EINVAL; /* only support VM_SHARED mapping */
1718 if (vma->vm_end - vma->vm_start != GO7007_BUF_SIZE)
1719 return -EINVAL; /* must map exactly one full buffer */
1720 mutex_lock(&gofh->lock);
1721 index = vma->vm_pgoff / GO7007_BUF_PAGES;
1722 if (index >= gofh->buf_count) {
1723 mutex_unlock(&gofh->lock);
1724 return -EINVAL; /* trying to map beyond requested buffers */
1726 if (index * GO7007_BUF_PAGES != vma->vm_pgoff) {
1727 mutex_unlock(&gofh->lock);
1728 return -EINVAL; /* offset is not aligned on buffer boundary */
1730 if (gofh->bufs[index].mapped > 0) {
1731 mutex_unlock(&gofh->lock);
1732 return -EBUSY;
1734 gofh->bufs[index].mapped = 1;
1735 gofh->bufs[index].user_addr = vma->vm_start;
1736 vma->vm_ops = &go7007_vm_ops;
1737 vma->vm_flags |= VM_DONTEXPAND;
1738 vma->vm_flags &= ~VM_IO;
1739 vma->vm_private_data = &gofh->bufs[index];
1740 mutex_unlock(&gofh->lock);
1741 return 0;
1744 static unsigned int go7007_poll(struct file *file, poll_table *wait)
1746 struct go7007_file *gofh = file->private_data;
1747 struct go7007_buffer *gobuf;
1749 if (list_empty(&gofh->go->stream))
1750 return POLLERR;
1751 gobuf = list_entry(gofh->go->stream.next, struct go7007_buffer, stream);
1752 poll_wait(file, &gofh->go->frame_waitq, wait);
1753 if (gobuf->state == BUF_STATE_DONE)
1754 return POLLIN | POLLRDNORM;
1755 return 0;
1758 static void go7007_vfl_release(struct video_device *vfd)
1760 struct go7007 *go = video_get_drvdata(vfd);
1762 video_device_release(vfd);
1763 if (--go->ref_count == 0)
1764 kfree(go);
1767 static struct v4l2_file_operations go7007_fops = {
1768 .owner = THIS_MODULE,
1769 .open = go7007_open,
1770 .release = go7007_release,
1771 .ioctl = video_ioctl2,
1772 .read = go7007_read,
1773 .mmap = go7007_mmap,
1774 .poll = go7007_poll,
1777 static const struct v4l2_ioctl_ops video_ioctl_ops = {
1778 .vidioc_querycap = vidioc_querycap,
1779 .vidioc_enum_fmt_vid_cap = vidioc_enum_fmt_vid_cap,
1780 .vidioc_g_fmt_vid_cap = vidioc_g_fmt_vid_cap,
1781 .vidioc_try_fmt_vid_cap = vidioc_try_fmt_vid_cap,
1782 .vidioc_s_fmt_vid_cap = vidioc_s_fmt_vid_cap,
1783 .vidioc_reqbufs = vidioc_reqbufs,
1784 .vidioc_querybuf = vidioc_querybuf,
1785 .vidioc_qbuf = vidioc_qbuf,
1786 .vidioc_dqbuf = vidioc_dqbuf,
1787 .vidioc_g_std = vidioc_g_std,
1788 .vidioc_s_std = vidioc_s_std,
1789 .vidioc_querystd = vidioc_querystd,
1790 .vidioc_enum_input = vidioc_enum_input,
1791 .vidioc_g_input = vidioc_g_input,
1792 .vidioc_s_input = vidioc_s_input,
1793 .vidioc_queryctrl = vidioc_queryctrl,
1794 .vidioc_g_ctrl = vidioc_g_ctrl,
1795 .vidioc_s_ctrl = vidioc_s_ctrl,
1796 .vidioc_streamon = vidioc_streamon,
1797 .vidioc_streamoff = vidioc_streamoff,
1798 .vidioc_g_tuner = vidioc_g_tuner,
1799 .vidioc_s_tuner = vidioc_s_tuner,
1800 .vidioc_g_frequency = vidioc_g_frequency,
1801 .vidioc_s_frequency = vidioc_s_frequency,
1802 .vidioc_g_parm = vidioc_g_parm,
1803 .vidioc_s_parm = vidioc_s_parm,
1804 .vidioc_enum_framesizes = vidioc_enum_framesizes,
1805 .vidioc_enum_frameintervals = vidioc_enum_frameintervals,
1806 .vidioc_cropcap = vidioc_cropcap,
1807 .vidioc_g_crop = vidioc_g_crop,
1808 .vidioc_s_crop = vidioc_s_crop,
1809 .vidioc_g_jpegcomp = vidioc_g_jpegcomp,
1810 .vidioc_s_jpegcomp = vidioc_s_jpegcomp,
1813 static struct video_device go7007_template = {
1814 .name = "go7007",
1815 .fops = &go7007_fops,
1816 .minor = -1,
1817 .release = go7007_vfl_release,
1818 .ioctl_ops = &video_ioctl_ops,
1819 .tvnorms = V4L2_STD_ALL,
1820 .current_norm = V4L2_STD_NTSC,
1823 int go7007_v4l2_init(struct go7007 *go)
1825 int rv;
1827 go->video_dev = video_device_alloc();
1828 if (go->video_dev == NULL)
1829 return -ENOMEM;
1830 memcpy(go->video_dev, &go7007_template, sizeof(go7007_template));
1831 go->video_dev->parent = go->dev;
1832 rv = video_register_device(go->video_dev, VFL_TYPE_GRABBER, -1);
1833 if (rv < 0) {
1834 video_device_release(go->video_dev);
1835 go->video_dev = NULL;
1836 return rv;
1838 video_set_drvdata(go->video_dev, go);
1839 ++go->ref_count;
1840 printk(KERN_INFO "%s: registered device video%d [v4l2]\n",
1841 go->video_dev->name, go->video_dev->num);
1843 return 0;
1846 void go7007_v4l2_remove(struct go7007 *go)
1848 unsigned long flags;
1850 mutex_lock(&go->hw_lock);
1851 if (go->streaming) {
1852 go->streaming = 0;
1853 go7007_stream_stop(go);
1854 spin_lock_irqsave(&go->spinlock, flags);
1855 abort_queued(go);
1856 spin_unlock_irqrestore(&go->spinlock, flags);
1858 mutex_unlock(&go->hw_lock);
1859 if (go->video_dev)
1860 video_unregister_device(go->video_dev);