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