1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
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/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>
36
37#include "go7007.h"
38#include "go7007-priv.h"
39#include "wis-i2c.h"
40
41
42#ifndef V4L2_MPEG_STREAM_TYPE_MPEG_ELEM
43#define V4L2_MPEG_STREAM_TYPE_MPEG_ELEM 6
44#endif
45#ifndef V4L2_MPEG_VIDEO_ENCODING_MPEG_4
46#define V4L2_MPEG_VIDEO_ENCODING_MPEG_4 3
47#endif
48
49static void deactivate_buffer(struct go7007_buffer *gobuf)
50{
51 int i;
52
53 if (gobuf->state != BUF_STATE_IDLE) {
54 list_del(&gobuf->stream);
55 gobuf->state = BUF_STATE_IDLE;
56 }
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;
61 }
62}
63
64static void abort_queued(struct go7007 *go)
65{
66 struct go7007_buffer *gobuf, *next;
67
68 list_for_each_entry_safe(gobuf, next, &go->stream, stream) {
69 deactivate_buffer(gobuf);
70 }
71}
72
73static int go7007_streamoff(struct go7007 *go)
74{
75 int retval = -EINVAL;
76 unsigned long flags;
77
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;
87 }
88 mutex_unlock(&go->hw_lock);
89 return 0;
90}
91
92static int go7007_open(struct file *file)
93{
94 struct go7007 *go = video_get_drvdata(video_devdata(file));
95 struct go7007_file *gofh;
96
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;
108}
109
110static int go7007_release(struct file *file)
111{
112 struct go7007_file *gofh = file->private_data;
113 struct go7007 *go = gofh->go;
114
115 if (gofh->buf_count > 0) {
116 go7007_streamoff(go);
117 go->in_use = 0;
118 kfree(gofh->bufs);
119 gofh->buf_count = 0;
120 }
121 kfree(gofh);
122 if (--go->ref_count == 0)
123 kfree(go);
124 file->private_data = NULL;
125 return 0;
126}
127
128static u32 get_frame_type_flag(struct go7007_buffer *gobuf, int format)
129{
130 u8 *f = page_address(gobuf->pages[0]);
131
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;
145 }
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;
157 }
158 }
159
160 return 0;
161}
162
163static int set_capture_size(struct go7007 *go, struct v4l2_format *fmt, int try)
164{
165 int sensor_height = 0, sensor_width = 0;
166 int width, height, i;
167
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;
172
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;
186 }
187
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;
198
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;
208
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;
218 }
219 width &= ~0xf;
220 height &= ~0xf;
221 }
222
223 if (fmt != NULL) {
224 u32 pixelformat = fmt->fmt.pix.pixelformat;
225
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;
235 }
236
237 if (try)
238 return 0;
239
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;
248
249 if (go->board_info->sensor_flags & GO7007_SENSOR_SCALING) {
250 struct video_decoder_resolution res;
251
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;
259 }
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;
276 }
277 }
278
279 if (fmt == NULL)
280 return 0;
281
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
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;
326 }
327 return 0;
328}
329
330#if 0
331static int clip_to_modet_map(struct go7007 *go, int region,
332 struct v4l2_clip *clip_list)
333{
334 struct v4l2_clip clip, *clip_ptr;
335 int x, y, mbnum;
336
337
338
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;
361 }
362 clip_ptr = clip.next;
363 }
364
365
366 for (mbnum = 0; mbnum < 1624; ++mbnum)
367 if (go->modet_map[mbnum] == region)
368 go->modet_map[mbnum] = 0;
369
370
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;
381 }
382 clip_ptr = clip.next;
383 }
384 return 0;
385}
386#endif
387
388static int mpeg_queryctrl(struct v4l2_queryctrl *ctrl)
389{
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,
398 0
399 };
400 static const u32 *ctrl_classes[] = {
401 mpeg_ctrls,
402 NULL
403 };
404
405 ctrl->id = v4l2_ctrl_next(ctrl_classes, ctrl->id);
406
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;
436 }
437 return 0;
438}
439
440static int mpeg_s_ctrl(struct v4l2_control *ctrl, struct go7007 *go)
441{
442
443 if (go->streaming)
444 return -EBUSY;
445
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
462 break;
463 default:
464 return -EINVAL;
465 }
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
476
477
478 go->pali = 0x48;
479 break;
480 case V4L2_MPEG_VIDEO_ENCODING_MPEG_4:
481 go->format = GO7007_FORMAT_MPEG4;
482
483
484
485 go->pali = 0xf5;
486 break;
487 default:
488 return -EINVAL;
489 }
490 go->gop_header_enable =
491
492 1;
493
494
495
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;
515 }
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
529 if (ctrl->value < 64000 || ctrl->value > 10000000)
530 return -EINVAL;
531 go->bitrate = ctrl->value;
532 break;
533 default:
534 return -EINVAL;
535 }
536 return 0;
537}
538
539static int mpeg_g_ctrl(struct v4l2_control *ctrl, struct go7007 *go)
540{
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;
561 }
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;
576 }
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;
589 }
590 return 0;
591}
592
593static int vidioc_querycap(struct file *file, void *priv,
594 struct v4l2_capability *cap)
595{
596 struct go7007 *go = ((struct go7007_file *) priv)->go;
597
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
603
604 cap->version = KERNEL_VERSION(0, 9, 8);
605
606 cap->capabilities = V4L2_CAP_VIDEO_CAPTURE |
607 V4L2_CAP_STREAMING;
608
609 if (go->board_info->flags & GO7007_BOARD_HAS_TUNER)
610 cap->capabilities |= V4L2_CAP_TUNER;
611
612 return 0;
613}
614
615static int vidioc_enum_fmt_vid_cap(struct file *file, void *priv,
616 struct v4l2_fmtdesc *fmt)
617{
618 char *desc = NULL;
619
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;
631 }
632 fmt->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
633 fmt->flags = V4L2_FMT_FLAG_COMPRESSED;
634
635 strncpy(fmt->description, desc, sizeof(fmt->description));
636
637 return 0;
638}
639
640static int vidioc_g_fmt_vid_cap(struct file *file, void *priv,
641 struct v4l2_format *fmt)
642{
643 struct go7007 *go = ((struct go7007_file *) priv)->go;
644
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;
654
655 return 0;
656}
657
658static int vidioc_try_fmt_vid_cap(struct file *file, void *priv,
659 struct v4l2_format *fmt)
660{
661 struct go7007 *go = ((struct go7007_file *) priv)->go;
662
663 return set_capture_size(go, fmt, 1);
664}
665
666static int vidioc_s_fmt_vid_cap(struct file *file, void *priv,
667 struct v4l2_format *fmt)
668{
669 struct go7007 *go = ((struct go7007_file *) priv)->go;
670
671 if (go->streaming)
672 return -EBUSY;
673
674 return set_capture_size(go, fmt, 0);
675}
676
677static int vidioc_reqbufs(struct file *file, void *priv,
678 struct v4l2_requestbuffers *req)
679{
680 struct go7007_file *gofh = priv;
681 struct go7007 *go = gofh->go;
682 int retval = -EBUSY;
683 unsigned int count, i;
684
685 if (go->streaming)
686 return retval;
687
688 if (req->type != V4L2_BUF_TYPE_VIDEO_CAPTURE ||
689 req->memory != V4L2_MEMORY_MMAP)
690 return -EINVAL;
691
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;
696
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;
701 }
702
703 if (gofh->buf_count > 0)
704 kfree(gofh->bufs);
705
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;
713
714 gofh->bufs = kmalloc(count * sizeof(struct go7007_buffer),
715 GFP_KERNEL);
716
717 if (!gofh->bufs) {
718 mutex_unlock(&go->hw_lock);
719 goto unlock_and_return;
720 }
721
722 memset(gofh->bufs, 0, count * sizeof(struct go7007_buffer));
723
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;
729 }
730
731 go->in_use = 1;
732 } else {
733 go->in_use = 0;
734 }
735
736 gofh->buf_count = count;
737 mutex_unlock(&go->hw_lock);
738 mutex_unlock(&gofh->lock);
739
740 memset(req, 0, sizeof(*req));
741
742 req->count = count;
743 req->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
744 req->memory = V4L2_MEMORY_MMAP;
745
746 return 0;
747
748unlock_and_return:
749 mutex_unlock(&gofh->lock);
750 return retval;
751}
752
753static int vidioc_querybuf(struct file *file, void *priv,
754 struct v4l2_buffer *buf)
755{
756 struct go7007_file *gofh = priv;
757 int retval = -EINVAL;
758 unsigned int index;
759
760 if (buf->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
761 return retval;
762
763 index = buf->index;
764
765 mutex_lock(&gofh->lock);
766 if (index >= gofh->buf_count)
767 goto unlock_and_return;
768
769 memset(buf, 0, sizeof(*buf));
770 buf->index = index;
771 buf->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
772
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;
782 }
783
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);
790
791 return 0;
792
793unlock_and_return:
794 mutex_unlock(&gofh->lock);
795 return retval;
796}
797
798static int vidioc_qbuf(struct file *file, void *priv, struct v4l2_buffer *buf)
799{
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;
806
807 if (buf->type != V4L2_BUF_TYPE_VIDEO_CAPTURE ||
808 buf->memory != V4L2_MEMORY_MMAP)
809 return retval;
810
811 mutex_lock(&gofh->lock);
812 if (buf->index < 0 || buf->index >= gofh->buf_count)
813 goto unlock_and_return;
814
815 gobuf = &gofh->bufs[buf->index];
816 if (!gobuf->mapped)
817 goto unlock_and_return;
818
819 retval = -EBUSY;
820 if (gobuf->state != BUF_STATE_IDLE)
821 goto unlock_and_return;
822
823
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;
832
833 retval = -ENOMEM;
834 down_read(¤t->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(¤t->mm->mmap_sem);
839
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;
846 }
847
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);
853
854 return 0;
855
856unlock_and_return:
857 mutex_unlock(&gofh->lock);
858 return retval;
859}
860
861
862static int vidioc_dqbuf(struct file *file, void *priv, struct v4l2_buffer *buf)
863{
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);
871
872 if (buf->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
873 return retval;
874 if (buf->memory != V4L2_MEMORY_MMAP)
875 return retval;
876
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);
882
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;
894 }
895 schedule();
896 }
897 finish_wait(&go->frame_waitq, &wait);
898 }
899 if (gobuf->state != BUF_STATE_DONE)
900 goto unlock_and_return;
901
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;
907
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;
920
921 mutex_unlock(&gofh->lock);
922 return 0;
923
924unlock_and_return:
925 mutex_unlock(&gofh->lock);
926 return retval;
927}
928
929static int vidioc_streamon(struct file *file, void *priv,
930 enum v4l2_buf_type type)
931{
932 struct go7007_file *gofh = priv;
933 struct go7007 *go = gofh->go;
934 int retval = 0;
935
936 if (type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
937 return -EINVAL;
938
939 mutex_lock(&gofh->lock);
940 mutex_lock(&go->hw_lock);
941
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;
950 }
951 mutex_unlock(&go->hw_lock);
952 mutex_unlock(&gofh->lock);
953
954 return retval;
955}
956
957static int vidioc_streamoff(struct file *file, void *priv,
958 enum v4l2_buf_type type)
959{
960 struct go7007_file *gofh = priv;
961 struct go7007 *go = gofh->go;
962
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);
968
969 return 0;
970}
971
972static int vidioc_queryctrl(struct file *file, void *priv,
973 struct v4l2_queryctrl *query)
974{
975 struct go7007 *go = ((struct go7007_file *) priv)->go;
976
977 if (!go->i2c_adapter_online)
978 return -EIO;
979
980 i2c_clients_command(&go->i2c_adapter, VIDIOC_QUERYCTRL, query);
981
982 return (!query->name[0]) ? mpeg_queryctrl(query) : 0;
983}
984
985static int vidioc_g_ctrl(struct file *file, void *priv,
986 struct v4l2_control *ctrl)
987{
988 struct go7007 *go = ((struct go7007_file *) priv)->go;
989 struct v4l2_queryctrl query;
990
991 if (!go->i2c_adapter_online)
992 return -EIO;
993
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);
1000
1001 return 0;
1002}
1003
1004static int vidioc_s_ctrl(struct file *file, void *priv,
1005 struct v4l2_control *ctrl)
1006{
1007 struct go7007 *go = ((struct go7007_file *) priv)->go;
1008 struct v4l2_queryctrl query;
1009
1010 if (!go->i2c_adapter_online)
1011 return -EIO;
1012
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);
1019
1020 return 0;
1021}
1022
1023static int vidioc_g_parm(struct file *filp, void *priv,
1024 struct v4l2_streamparm *parm)
1025{
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,
1030 };
1031
1032 if (parm->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
1033 return -EINVAL;
1034
1035 parm->parm.capture.capability |= V4L2_CAP_TIMEPERFRAME;
1036 parm->parm.capture.timeperframe = timeperframe;
1037
1038 return 0;
1039}
1040
1041static int vidioc_s_parm(struct file *filp, void *priv,
1042 struct v4l2_streamparm *parm)
1043{
1044 struct go7007 *go = ((struct go7007_file *) priv)->go;
1045 unsigned int n, d;
1046
1047 if (parm->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
1048 return -EINVAL;
1049 if (parm->parm.capture.capturemode != 0)
1050 return -EINVAL;
1051
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;
1059
1060 return 0;
1061}
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073static int vidioc_enum_framesizes(struct file *filp, void *priv,
1074 struct v4l2_frmsizeenum *fsize)
1075{
1076 struct go7007 *go = ((struct go7007_file *) priv)->go;
1077
1078
1079 if ((go->board_info->flags & GO7007_BOARD_HAS_TUNER) ||
1080 (go->board_info->sensor_flags & GO7007_SENSOR_TV))
1081 return -EINVAL;
1082
1083 if (fsize->index > 0)
1084 return -EINVAL;
1085
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;
1089
1090 return 0;
1091}
1092
1093static int vidioc_enum_frameintervals(struct file *filp, void *priv,
1094 struct v4l2_frmivalenum *fival)
1095{
1096 struct go7007 *go = ((struct go7007_file *) priv)->go;
1097
1098
1099 if ((go->board_info->flags & GO7007_BOARD_HAS_TUNER) ||
1100 (go->board_info->sensor_flags & GO7007_SENSOR_TV))
1101 return -EINVAL;
1102
1103 if (fival->index > 0)
1104 return -EINVAL;
1105
1106 fival->type = V4L2_FRMIVAL_TYPE_DISCRETE;
1107 fival->discrete.numerator = 1001;
1108 fival->discrete.denominator = go->board_info->sensor_framerate;
1109
1110 return 0;
1111}
1112
1113static int vidioc_g_std(struct file *file, void *priv, v4l2_std_id *std)
1114{
1115 struct go7007 *go = ((struct go7007_file *) priv)->go;
1116
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;
1126 }
1127
1128 return 0;
1129}
1130
1131static int vidioc_s_std(struct file *file, void *priv, v4l2_std_id *std)
1132{
1133 struct go7007 *go = ((struct go7007_file *) priv)->go;
1134
1135 if (go->streaming)
1136 return -EBUSY;
1137
1138 if (!(go->board_info->sensor_flags & GO7007_SENSOR_TV) &&
1139 *std != 0)
1140 return -EINVAL;
1141
1142 if (*std == 0)
1143 return -EINVAL;
1144
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)
1152 return -EINVAL;
1153 }
1154
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;
1166
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);
1171
1172 return 0;
1173}
1174
1175static int vidioc_querystd(struct file *file, void *priv, v4l2_std_id *std)
1176{
1177 struct go7007 *go = ((struct go7007_file *) priv)->go;
1178
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;
1188
1189 return 0;
1190}
1191
1192static int vidioc_enum_input(struct file *file, void *priv,
1193 struct v4l2_input *inp)
1194{
1195 struct go7007 *go = ((struct go7007_file *) priv)->go;
1196
1197 if (inp->index >= go->board_info->num_inputs)
1198 return -EINVAL;
1199
1200 strncpy(inp->name, go->board_info->inputs[inp->index].name,
1201 sizeof(inp->name));
1202
1203
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;
1209
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;
1217
1218 return 0;
1219}
1220
1221
1222static int vidioc_g_input(struct file *file, void *priv, unsigned int *input)
1223{
1224 struct go7007 *go = ((struct go7007_file *) priv)->go;
1225
1226 *input = go->input;
1227
1228 return 0;
1229}
1230
1231static int vidioc_s_input(struct file *file, void *priv, unsigned int input)
1232{
1233 struct go7007 *go = ((struct go7007_file *) priv)->go;
1234
1235 if (input >= go->board_info->num_inputs)
1236 return -EINVAL;
1237 if (go->streaming)
1238 return -EBUSY;
1239
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);
1246 }
1247
1248 return 0;
1249}
1250
1251static int vidioc_g_tuner(struct file *file, void *priv,
1252 struct v4l2_tuner *t)
1253{
1254 struct go7007 *go = ((struct go7007_file *) priv)->go;
1255
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;
1262
1263 i2c_clients_command(&go->i2c_adapter, VIDIOC_G_TUNER, t);
1264
1265 t->index = 0;
1266 return 0;
1267}
1268
1269static int vidioc_s_tuner(struct file *file, void *priv,
1270 struct v4l2_tuner *t)
1271{
1272 struct go7007 *go = ((struct go7007_file *) priv)->go;
1273
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;
1280
1281 switch (go->board_id) {
1282 case GO7007_BOARDID_PX_TV402U_NA:
1283 case GO7007_BOARDID_PX_TV402U_JP:
1284
1285 if (t->audmode != V4L2_TUNER_MODE_STEREO)
1286 return -EINVAL;
1287 break;
1288 }
1289
1290 i2c_clients_command(&go->i2c_adapter, VIDIOC_S_TUNER, t);
1291
1292 return 0;
1293}
1294
1295static int vidioc_g_frequency(struct file *file, void *priv,
1296 struct v4l2_frequency *f)
1297{
1298 struct go7007 *go = ((struct go7007_file *) priv)->go;
1299
1300 if (!(go->board_info->flags & GO7007_BOARD_HAS_TUNER))
1301 return -EINVAL;
1302 if (!go->i2c_adapter_online)
1303 return -EIO;
1304
1305 f->type = V4L2_TUNER_ANALOG_TV;
1306 i2c_clients_command(&go->i2c_adapter, VIDIOC_G_FREQUENCY, f);
1307 return 0;
1308}
1309
1310static int vidioc_s_frequency(struct file *file, void *priv,
1311 struct v4l2_frequency *f)
1312{
1313 struct go7007 *go = ((struct go7007_file *) priv)->go;
1314
1315 if (!(go->board_info->flags & GO7007_BOARD_HAS_TUNER))
1316 return -EINVAL;
1317 if (!go->i2c_adapter_online)
1318 return -EIO;
1319
1320 i2c_clients_command(&go->i2c_adapter, VIDIOC_S_FREQUENCY, f);
1321
1322 return 0;
1323}
1324
1325static int vidioc_cropcap(struct file *file, void *priv,
1326 struct v4l2_cropcap *cropcap)
1327{
1328 struct go7007 *go = ((struct go7007_file *) priv)->go;
1329
1330 if (cropcap->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
1331 return -EINVAL;
1332
1333
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;
1365 }
1366
1367 return 0;
1368}
1369
1370static int vidioc_g_crop(struct file *file, void *priv, struct v4l2_crop *crop)
1371{
1372 struct go7007 *go = ((struct go7007_file *) priv)->go;
1373
1374 if (crop->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
1375 return -EINVAL;
1376
1377 crop->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
1378
1379
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;
1399 }
1400
1401 return 0;
1402}
1403
1404
1405
1406static int vidioc_s_crop(struct file *file, void *priv, struct v4l2_crop *crop)
1407{
1408 if (crop->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
1409 return -EINVAL;
1410
1411 return 0;
1412}
1413
1414static int vidioc_g_jpegcomp(struct file *file, void *priv,
1415 struct v4l2_jpegcompression *params)
1416{
1417 memset(params, 0, sizeof(*params));
1418 params->quality = 50;
1419 params->jpeg_markers = V4L2_JPEG_MARKER_DHT |
1420 V4L2_JPEG_MARKER_DQT;
1421
1422 return 0;
1423}
1424
1425static int vidioc_s_jpegcomp(struct file *file, void *priv,
1426 struct v4l2_jpegcompression *params)
1427{
1428 if (params->quality != 50 ||
1429 params->jpeg_markers != (V4L2_JPEG_MARKER_DHT |
1430 V4L2_JPEG_MARKER_DQT))
1431 return -EINVAL;
1432
1433 return 0;
1434}
1435
1436
1437
1438
1439
1440
1441
1442
1443#if 0
1444
1445 case GO7007IOC_S_BITRATE:
1446 {
1447 int *bitrate = arg;
1448
1449 if (go->streaming)
1450 return -EINVAL;
1451
1452 if (*bitrate < 64000 || *bitrate > 10000000)
1453 return -EINVAL;
1454 go->bitrate = *bitrate;
1455 return 0;
1456 }
1457 case GO7007IOC_G_BITRATE:
1458 {
1459 int *bitrate = arg;
1460
1461 *bitrate = go->bitrate;
1462 return 0;
1463 }
1464 case GO7007IOC_S_COMP_PARAMS:
1465 {
1466 struct go7007_comp_params *comp = arg;
1467
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
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;
1490 }
1491 }
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;
1497 }
1498
1499 }
1500 case GO7007IOC_G_COMP_PARAMS:
1501 {
1502 struct go7007_comp_params *comp = arg;
1503
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;
1529 }
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;
1535 }
1536 case GO7007IOC_S_MPEG_PARAMS:
1537 {
1538 struct go7007_mpeg_params *mpeg = arg;
1539
1540 if (go->format != GO7007_FORMAT_MPEG1 &&
1541 go->format != GO7007_FORMAT_MPEG2 &&
1542 go->format != GO7007_FORMAT_MPEG4)
1543 return -EINVAL;
1544
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;
1577 }
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;
1586 }
1587
1588 }
1589 case GO7007IOC_G_MPEG_PARAMS:
1590 {
1591 struct go7007_mpeg_params *mpeg = arg;
1592
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;
1609 }
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;
1617 }
1618 case GO7007IOC_S_MD_PARAMS:
1619 {
1620 struct go7007_md_params *mdp = arg;
1621
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
1635 }
1636 case GO7007IOC_G_MD_PARAMS:
1637 {
1638 struct go7007_md_params *mdp = arg;
1639 int region = mdp->region;
1640
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;
1654 }
1655 case GO7007IOC_S_MD_REGION:
1656 {
1657 struct go7007_md_region *region = arg;
1658
1659 if (region->region < 1 || region->region > 3)
1660 return -EINVAL;
1661 return clip_to_modet_map(go, region->region, region->clips);
1662 }
1663#endif
1664
1665static ssize_t go7007_read(struct file *file, char __user *data,
1666 size_t count, loff_t *ppos)
1667{
1668 return -EINVAL;
1669}
1670
1671static void go7007_vm_open(struct vm_area_struct *vma)
1672{
1673 struct go7007_buffer *gobuf = vma->vm_private_data;
1674
1675 ++gobuf->mapped;
1676}
1677
1678static void go7007_vm_close(struct vm_area_struct *vma)
1679{
1680 struct go7007_buffer *gobuf = vma->vm_private_data;
1681 unsigned long flags;
1682
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);
1687 }
1688}
1689
1690
1691static int go7007_vm_fault(struct vm_area_struct *vma, struct vm_fault *vmf)
1692{
1693 struct page *page;
1694
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;
1701}
1702
1703static struct vm_operations_struct go7007_vm_ops = {
1704 .open = go7007_vm_open,
1705 .close = go7007_vm_close,
1706 .fault = go7007_vm_fault,
1707};
1708
1709static int go7007_mmap(struct file *file, struct vm_area_struct *vma)
1710{
1711 struct go7007_file *gofh = file->private_data;
1712 unsigned int index;
1713
1714 if (gofh->go->status != STATUS_ONLINE)
1715 return -EIO;
1716 if (!(vma->vm_flags & VM_SHARED))
1717 return -EINVAL;
1718 if (vma->vm_end - vma->vm_start != GO7007_BUF_SIZE)
1719 return -EINVAL;
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;
1725 }
1726 if (index * GO7007_BUF_PAGES != vma->vm_pgoff) {
1727 mutex_unlock(&gofh->lock);
1728 return -EINVAL;
1729 }
1730 if (gofh->bufs[index].mapped > 0) {
1731 mutex_unlock(&gofh->lock);
1732 return -EBUSY;
1733 }
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;
1742}
1743
1744static unsigned int go7007_poll(struct file *file, poll_table *wait)
1745{
1746 struct go7007_file *gofh = file->private_data;
1747 struct go7007_buffer *gobuf;
1748
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;
1756}
1757
1758static void go7007_vfl_release(struct video_device *vfd)
1759{
1760 struct go7007 *go = video_get_drvdata(vfd);
1761
1762 video_device_release(vfd);
1763 if (--go->ref_count == 0)
1764 kfree(go);
1765}
1766
1767static 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,
1775};
1776
1777static 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,
1811};
1812
1813static 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,
1821};
1822
1823int go7007_v4l2_init(struct go7007 *go)
1824{
1825 int rv;
1826
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;
1837 }
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);
1842
1843 return 0;
1844}
1845
1846void go7007_v4l2_remove(struct go7007 *go)
1847{
1848 unsigned long flags;
1849
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);
1857 }
1858 mutex_unlock(&go->hw_lock);
1859 if (go->video_dev)
1860 video_unregister_device(go->video_dev);
1861}
1862