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/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
43#ifndef V4L2_MPEG_STREAM_TYPE_MPEG_ELEM
44#define V4L2_MPEG_STREAM_TYPE_MPEG_ELEM 6
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 = kzalloc(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
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
343
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
371 for (mbnum = 0; mbnum < 1624; ++mbnum)
372 if (go->modet_map[mbnum] == region)
373 go->modet_map[mbnum] = 0;
374
375
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
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
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
481
482
483 go->pali = 0x48;
484 break;
485 case V4L2_MPEG_VIDEO_ENCODING_MPEG_4:
486 go->format = GO7007_FORMAT_MPEG4;
487
488
489
490 go->pali = 0xf5;
491 break;
492 default:
493 return -EINVAL;
494 }
495 go->gop_header_enable =
496
497 1;
498
499
500
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
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;
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 >= 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
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 call_all(&go->v4l2_dev, video, s_stream, 1);
957
958 return retval;
959}
960
961static int vidioc_streamoff(struct file *file, void *priv,
962 enum v4l2_buf_type type)
963{
964 struct go7007_file *gofh = priv;
965 struct go7007 *go = gofh->go;
966
967 if (type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
968 return -EINVAL;
969 mutex_lock(&gofh->lock);
970 go7007_streamoff(go);
971 mutex_unlock(&gofh->lock);
972 call_all(&go->v4l2_dev, video, s_stream, 0);
973
974 return 0;
975}
976
977static int vidioc_queryctrl(struct file *file, void *priv,
978 struct v4l2_queryctrl *query)
979{
980 struct go7007 *go = ((struct go7007_file *) priv)->go;
981 int id = query->id;
982
983 if (0 == call_all(&go->v4l2_dev, core, queryctrl, query))
984 return 0;
985
986 query->id = id;
987 return mpeg_query_ctrl(query);
988}
989
990static int vidioc_g_ctrl(struct file *file, void *priv,
991 struct v4l2_control *ctrl)
992{
993 struct go7007 *go = ((struct go7007_file *) priv)->go;
994
995 if (0 == call_all(&go->v4l2_dev, core, g_ctrl, ctrl))
996 return 0;
997
998 return mpeg_g_ctrl(ctrl, go);
999}
1000
1001static int vidioc_s_ctrl(struct file *file, void *priv,
1002 struct v4l2_control *ctrl)
1003{
1004 struct go7007 *go = ((struct go7007_file *) priv)->go;
1005
1006 if (0 == call_all(&go->v4l2_dev, core, s_ctrl, ctrl))
1007 return 0;
1008
1009 return mpeg_s_ctrl(ctrl, go);
1010}
1011
1012static int vidioc_g_parm(struct file *filp, void *priv,
1013 struct v4l2_streamparm *parm)
1014{
1015 struct go7007 *go = ((struct go7007_file *) priv)->go;
1016 struct v4l2_fract timeperframe = {
1017 .numerator = 1001 * go->fps_scale,
1018 .denominator = go->sensor_framerate,
1019 };
1020
1021 if (parm->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
1022 return -EINVAL;
1023
1024 parm->parm.capture.capability |= V4L2_CAP_TIMEPERFRAME;
1025 parm->parm.capture.timeperframe = timeperframe;
1026
1027 return 0;
1028}
1029
1030static int vidioc_s_parm(struct file *filp, void *priv,
1031 struct v4l2_streamparm *parm)
1032{
1033 struct go7007 *go = ((struct go7007_file *) priv)->go;
1034 unsigned int n, d;
1035
1036 if (parm->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
1037 return -EINVAL;
1038 if (parm->parm.capture.capturemode != 0)
1039 return -EINVAL;
1040
1041 n = go->sensor_framerate *
1042 parm->parm.capture.timeperframe.numerator;
1043 d = 1001 * parm->parm.capture.timeperframe.denominator;
1044 if (n != 0 && d != 0 && n > d)
1045 go->fps_scale = (n + d/2) / d;
1046 else
1047 go->fps_scale = 1;
1048
1049 return 0;
1050}
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062static int vidioc_enum_framesizes(struct file *filp, void *priv,
1063 struct v4l2_frmsizeenum *fsize)
1064{
1065 struct go7007 *go = ((struct go7007_file *) priv)->go;
1066
1067
1068 if ((go->board_info->flags & GO7007_BOARD_HAS_TUNER) ||
1069 (go->board_info->sensor_flags & GO7007_SENSOR_TV))
1070 return -EINVAL;
1071
1072 if (fsize->index > 0)
1073 return -EINVAL;
1074
1075 fsize->type = V4L2_FRMSIZE_TYPE_DISCRETE;
1076 fsize->discrete.width = go->board_info->sensor_width;
1077 fsize->discrete.height = go->board_info->sensor_height;
1078
1079 return 0;
1080}
1081
1082static int vidioc_enum_frameintervals(struct file *filp, void *priv,
1083 struct v4l2_frmivalenum *fival)
1084{
1085 struct go7007 *go = ((struct go7007_file *) priv)->go;
1086
1087
1088 if ((go->board_info->flags & GO7007_BOARD_HAS_TUNER) ||
1089 (go->board_info->sensor_flags & GO7007_SENSOR_TV))
1090 return -EINVAL;
1091
1092 if (fival->index > 0)
1093 return -EINVAL;
1094
1095 fival->type = V4L2_FRMIVAL_TYPE_DISCRETE;
1096 fival->discrete.numerator = 1001;
1097 fival->discrete.denominator = go->board_info->sensor_framerate;
1098
1099 return 0;
1100}
1101
1102static int vidioc_g_std(struct file *file, void *priv, v4l2_std_id *std)
1103{
1104 struct go7007 *go = ((struct go7007_file *) priv)->go;
1105
1106 switch (go->standard) {
1107 case GO7007_STD_NTSC:
1108 *std = V4L2_STD_NTSC;
1109 break;
1110 case GO7007_STD_PAL:
1111 *std = V4L2_STD_PAL;
1112 break;
1113 default:
1114 return -EINVAL;
1115 }
1116
1117 return 0;
1118}
1119
1120static int vidioc_s_std(struct file *file, void *priv, v4l2_std_id *std)
1121{
1122 struct go7007 *go = ((struct go7007_file *) priv)->go;
1123
1124 if (go->streaming)
1125 return -EBUSY;
1126
1127 if (!(go->board_info->sensor_flags & GO7007_SENSOR_TV) && *std != 0)
1128 return -EINVAL;
1129
1130 if (*std == 0)
1131 return -EINVAL;
1132
1133 if ((go->board_info->flags & GO7007_BOARD_HAS_TUNER) &&
1134 go->input == go->board_info->num_inputs - 1) {
1135 if (!go->i2c_adapter_online)
1136 return -EIO;
1137 if (call_all(&go->v4l2_dev, core, s_std, *std) < 0)
1138 return -EINVAL;
1139 }
1140
1141 if (*std & V4L2_STD_NTSC) {
1142 go->standard = GO7007_STD_NTSC;
1143 go->sensor_framerate = 30000;
1144 } else if (*std & V4L2_STD_PAL) {
1145 go->standard = GO7007_STD_PAL;
1146 go->sensor_framerate = 25025;
1147 } else if (*std & V4L2_STD_SECAM) {
1148 go->standard = GO7007_STD_PAL;
1149 go->sensor_framerate = 25025;
1150 } else
1151 return -EINVAL;
1152
1153 call_all(&go->v4l2_dev, core, s_std, *std);
1154 set_capture_size(go, NULL, 0);
1155
1156 return 0;
1157}
1158
1159static int vidioc_querystd(struct file *file, void *priv, v4l2_std_id *std)
1160{
1161 struct go7007 *go = ((struct go7007_file *) priv)->go;
1162
1163 if ((go->board_info->flags & GO7007_BOARD_HAS_TUNER) &&
1164 go->input == go->board_info->num_inputs - 1) {
1165 if (!go->i2c_adapter_online)
1166 return -EIO;
1167 return call_all(&go->v4l2_dev, video, querystd, std);
1168 } else if (go->board_info->sensor_flags & GO7007_SENSOR_TV)
1169 *std = V4L2_STD_NTSC | V4L2_STD_PAL | V4L2_STD_SECAM;
1170 else
1171 *std = 0;
1172
1173 return 0;
1174}
1175
1176static int vidioc_enum_input(struct file *file, void *priv,
1177 struct v4l2_input *inp)
1178{
1179 struct go7007 *go = ((struct go7007_file *) priv)->go;
1180
1181 if (inp->index >= go->board_info->num_inputs)
1182 return -EINVAL;
1183
1184 strncpy(inp->name, go->board_info->inputs[inp->index].name,
1185 sizeof(inp->name));
1186
1187
1188 if ((go->board_info->flags & GO7007_BOARD_HAS_TUNER) &&
1189 inp->index == go->board_info->num_inputs - 1)
1190 inp->type = V4L2_INPUT_TYPE_TUNER;
1191 else
1192 inp->type = V4L2_INPUT_TYPE_CAMERA;
1193
1194 inp->audioset = 0;
1195 inp->tuner = 0;
1196 if (go->board_info->sensor_flags & GO7007_SENSOR_TV)
1197 inp->std = V4L2_STD_NTSC | V4L2_STD_PAL |
1198 V4L2_STD_SECAM;
1199 else
1200 inp->std = 0;
1201
1202 return 0;
1203}
1204
1205
1206static int vidioc_g_input(struct file *file, void *priv, unsigned int *input)
1207{
1208 struct go7007 *go = ((struct go7007_file *) priv)->go;
1209
1210 *input = go->input;
1211
1212 return 0;
1213}
1214
1215static int vidioc_s_input(struct file *file, void *priv, unsigned int input)
1216{
1217 struct go7007 *go = ((struct go7007_file *) priv)->go;
1218
1219 if (input >= go->board_info->num_inputs)
1220 return -EINVAL;
1221 if (go->streaming)
1222 return -EBUSY;
1223
1224 go->input = input;
1225
1226 return call_all(&go->v4l2_dev, video, s_routing, input, 0, 0);
1227}
1228
1229static int vidioc_g_tuner(struct file *file, void *priv,
1230 struct v4l2_tuner *t)
1231{
1232 struct go7007 *go = ((struct go7007_file *) priv)->go;
1233
1234 if (!(go->board_info->flags & GO7007_BOARD_HAS_TUNER))
1235 return -EINVAL;
1236 if (t->index != 0)
1237 return -EINVAL;
1238 if (!go->i2c_adapter_online)
1239 return -EIO;
1240
1241 return call_all(&go->v4l2_dev, tuner, g_tuner, t);
1242}
1243
1244static int vidioc_s_tuner(struct file *file, void *priv,
1245 struct v4l2_tuner *t)
1246{
1247 struct go7007 *go = ((struct go7007_file *) priv)->go;
1248
1249 if (!(go->board_info->flags & GO7007_BOARD_HAS_TUNER))
1250 return -EINVAL;
1251 if (t->index != 0)
1252 return -EINVAL;
1253 if (!go->i2c_adapter_online)
1254 return -EIO;
1255
1256 switch (go->board_id) {
1257 case GO7007_BOARDID_PX_TV402U_NA:
1258 case GO7007_BOARDID_PX_TV402U_JP:
1259
1260 if (t->audmode != V4L2_TUNER_MODE_STEREO)
1261 return -EINVAL;
1262 break;
1263 }
1264
1265 return call_all(&go->v4l2_dev, tuner, s_tuner, t);
1266}
1267
1268static int vidioc_g_frequency(struct file *file, void *priv,
1269 struct v4l2_frequency *f)
1270{
1271 struct go7007 *go = ((struct go7007_file *) priv)->go;
1272
1273 if (!(go->board_info->flags & GO7007_BOARD_HAS_TUNER))
1274 return -EINVAL;
1275 if (!go->i2c_adapter_online)
1276 return -EIO;
1277
1278 f->type = V4L2_TUNER_ANALOG_TV;
1279
1280 return call_all(&go->v4l2_dev, tuner, g_frequency, f);
1281}
1282
1283static int vidioc_s_frequency(struct file *file, void *priv,
1284 struct v4l2_frequency *f)
1285{
1286 struct go7007 *go = ((struct go7007_file *) priv)->go;
1287
1288 if (!(go->board_info->flags & GO7007_BOARD_HAS_TUNER))
1289 return -EINVAL;
1290 if (!go->i2c_adapter_online)
1291 return -EIO;
1292
1293 return call_all(&go->v4l2_dev, tuner, s_frequency, f);
1294}
1295
1296static int vidioc_cropcap(struct file *file, void *priv,
1297 struct v4l2_cropcap *cropcap)
1298{
1299 struct go7007 *go = ((struct go7007_file *) priv)->go;
1300
1301 if (cropcap->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
1302 return -EINVAL;
1303
1304
1305 switch (go->standard) {
1306 case GO7007_STD_NTSC:
1307 cropcap->bounds.top = 0;
1308 cropcap->bounds.left = 0;
1309 cropcap->bounds.width = 720;
1310 cropcap->bounds.height = 480;
1311 cropcap->defrect.top = 0;
1312 cropcap->defrect.left = 0;
1313 cropcap->defrect.width = 720;
1314 cropcap->defrect.height = 480;
1315 break;
1316 case GO7007_STD_PAL:
1317 cropcap->bounds.top = 0;
1318 cropcap->bounds.left = 0;
1319 cropcap->bounds.width = 720;
1320 cropcap->bounds.height = 576;
1321 cropcap->defrect.top = 0;
1322 cropcap->defrect.left = 0;
1323 cropcap->defrect.width = 720;
1324 cropcap->defrect.height = 576;
1325 break;
1326 case GO7007_STD_OTHER:
1327 cropcap->bounds.top = 0;
1328 cropcap->bounds.left = 0;
1329 cropcap->bounds.width = go->board_info->sensor_width;
1330 cropcap->bounds.height = go->board_info->sensor_height;
1331 cropcap->defrect.top = 0;
1332 cropcap->defrect.left = 0;
1333 cropcap->defrect.width = go->board_info->sensor_width;
1334 cropcap->defrect.height = go->board_info->sensor_height;
1335 break;
1336 }
1337
1338 return 0;
1339}
1340
1341static int vidioc_g_crop(struct file *file, void *priv, struct v4l2_crop *crop)
1342{
1343 struct go7007 *go = ((struct go7007_file *) priv)->go;
1344
1345 if (crop->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
1346 return -EINVAL;
1347
1348 crop->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
1349
1350
1351 switch (go->standard) {
1352 case GO7007_STD_NTSC:
1353 crop->c.top = 0;
1354 crop->c.left = 0;
1355 crop->c.width = 720;
1356 crop->c.height = 480;
1357 break;
1358 case GO7007_STD_PAL:
1359 crop->c.top = 0;
1360 crop->c.left = 0;
1361 crop->c.width = 720;
1362 crop->c.height = 576;
1363 break;
1364 case GO7007_STD_OTHER:
1365 crop->c.top = 0;
1366 crop->c.left = 0;
1367 crop->c.width = go->board_info->sensor_width;
1368 crop->c.height = go->board_info->sensor_height;
1369 break;
1370 }
1371
1372 return 0;
1373}
1374
1375
1376
1377static int vidioc_s_crop(struct file *file, void *priv, const struct v4l2_crop *crop)
1378{
1379 if (crop->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
1380 return -EINVAL;
1381
1382 return 0;
1383}
1384
1385static int vidioc_g_jpegcomp(struct file *file, void *priv,
1386 struct v4l2_jpegcompression *params)
1387{
1388 memset(params, 0, sizeof(*params));
1389 params->quality = 50;
1390 params->jpeg_markers = V4L2_JPEG_MARKER_DHT |
1391 V4L2_JPEG_MARKER_DQT;
1392
1393 return 0;
1394}
1395
1396static int vidioc_s_jpegcomp(struct file *file, void *priv,
1397 const struct v4l2_jpegcompression *params)
1398{
1399 if (params->quality != 50 ||
1400 params->jpeg_markers != (V4L2_JPEG_MARKER_DHT |
1401 V4L2_JPEG_MARKER_DQT))
1402 return -EINVAL;
1403
1404 return 0;
1405}
1406
1407
1408
1409
1410
1411
1412
1413
1414#if 0
1415
1416 case GO7007IOC_S_BITRATE:
1417 {
1418 int *bitrate = arg;
1419
1420 if (go->streaming)
1421 return -EINVAL;
1422
1423 if (*bitrate < 64000 || *bitrate > 10000000)
1424 return -EINVAL;
1425 go->bitrate = *bitrate;
1426 return 0;
1427 }
1428 case GO7007IOC_G_BITRATE:
1429 {
1430 int *bitrate = arg;
1431
1432 *bitrate = go->bitrate;
1433 return 0;
1434 }
1435 case GO7007IOC_S_COMP_PARAMS:
1436 {
1437 struct go7007_comp_params *comp = arg;
1438
1439 if (go->format == GO7007_FORMAT_MJPEG)
1440 return -EINVAL;
1441 if (comp->gop_size > 0)
1442 go->gop_size = comp->gop_size;
1443 else
1444 go->gop_size = go->sensor_framerate / 1000;
1445 if (go->gop_size != 15)
1446 go->dvd_mode = 0;
1447
1448 if (go->board_info->sensor_flags & GO7007_SENSOR_TV) {
1449 switch (comp->aspect_ratio) {
1450 case GO7007_ASPECT_RATIO_4_3_NTSC:
1451 case GO7007_ASPECT_RATIO_4_3_PAL:
1452 go->aspect_ratio = GO7007_RATIO_4_3;
1453 break;
1454 case GO7007_ASPECT_RATIO_16_9_NTSC:
1455 case GO7007_ASPECT_RATIO_16_9_PAL:
1456 go->aspect_ratio = GO7007_RATIO_16_9;
1457 break;
1458 default:
1459 go->aspect_ratio = GO7007_RATIO_1_1;
1460 break;
1461 }
1462 }
1463 if (comp->flags & GO7007_COMP_OMIT_SEQ_HEADER) {
1464 go->dvd_mode = 0;
1465 go->seq_header_enable = 0;
1466 } else {
1467 go->seq_header_enable = 1;
1468 }
1469
1470 }
1471 case GO7007IOC_G_COMP_PARAMS:
1472 {
1473 struct go7007_comp_params *comp = arg;
1474
1475 if (go->format == GO7007_FORMAT_MJPEG)
1476 return -EINVAL;
1477 memset(comp, 0, sizeof(*comp));
1478 comp->gop_size = go->gop_size;
1479 comp->max_b_frames = go->ipb ? 2 : 0;
1480 switch (go->aspect_ratio) {
1481 case GO7007_RATIO_4_3:
1482 if (go->standard == GO7007_STD_NTSC)
1483 comp->aspect_ratio =
1484 GO7007_ASPECT_RATIO_4_3_NTSC;
1485 else
1486 comp->aspect_ratio =
1487 GO7007_ASPECT_RATIO_4_3_PAL;
1488 break;
1489 case GO7007_RATIO_16_9:
1490 if (go->standard == GO7007_STD_NTSC)
1491 comp->aspect_ratio =
1492 GO7007_ASPECT_RATIO_16_9_NTSC;
1493 else
1494 comp->aspect_ratio =
1495 GO7007_ASPECT_RATIO_16_9_PAL;
1496 break;
1497 default:
1498 comp->aspect_ratio = GO7007_ASPECT_RATIO_1_1;
1499 break;
1500 }
1501 if (go->closed_gop)
1502 comp->flags |= GO7007_COMP_CLOSED_GOP;
1503 if (!go->seq_header_enable)
1504 comp->flags |= GO7007_COMP_OMIT_SEQ_HEADER;
1505 return 0;
1506 }
1507 case GO7007IOC_S_MPEG_PARAMS:
1508 {
1509 struct go7007_mpeg_params *mpeg = arg;
1510
1511 if (go->format != GO7007_FORMAT_MPEG1 &&
1512 go->format != GO7007_FORMAT_MPEG2 &&
1513 go->format != GO7007_FORMAT_MPEG4)
1514 return -EINVAL;
1515
1516 if (mpeg->flags & GO7007_MPEG_FORCE_DVD_MODE) {
1517 go->format = GO7007_FORMAT_MPEG2;
1518 go->bitrate = 9800000;
1519 go->gop_size = 15;
1520 go->pali = 0x48;
1521 go->closed_gop = 1;
1522 go->repeat_seqhead = 0;
1523 go->seq_header_enable = 1;
1524 go->gop_header_enable = 1;
1525 go->dvd_mode = 1;
1526 } else {
1527 switch (mpeg->mpeg_video_standard) {
1528 case GO7007_MPEG_VIDEO_MPEG1:
1529 go->format = GO7007_FORMAT_MPEG1;
1530 go->pali = 0;
1531 break;
1532 case GO7007_MPEG_VIDEO_MPEG2:
1533 go->format = GO7007_FORMAT_MPEG2;
1534 if (mpeg->pali >> 24 == 2)
1535 go->pali = mpeg->pali & 0xff;
1536 else
1537 go->pali = 0x48;
1538 break;
1539 case GO7007_MPEG_VIDEO_MPEG4:
1540 go->format = GO7007_FORMAT_MPEG4;
1541 if (mpeg->pali >> 24 == 4)
1542 go->pali = mpeg->pali & 0xff;
1543 else
1544 go->pali = 0xf5;
1545 break;
1546 default:
1547 return -EINVAL;
1548 }
1549 go->gop_header_enable =
1550 mpeg->flags & GO7007_MPEG_OMIT_GOP_HEADER
1551 ? 0 : 1;
1552 if (mpeg->flags & GO7007_MPEG_REPEAT_SEQHEADER)
1553 go->repeat_seqhead = 1;
1554 else
1555 go->repeat_seqhead = 0;
1556 go->dvd_mode = 0;
1557 }
1558
1559 }
1560 case GO7007IOC_G_MPEG_PARAMS:
1561 {
1562 struct go7007_mpeg_params *mpeg = arg;
1563
1564 memset(mpeg, 0, sizeof(*mpeg));
1565 switch (go->format) {
1566 case GO7007_FORMAT_MPEG1:
1567 mpeg->mpeg_video_standard = GO7007_MPEG_VIDEO_MPEG1;
1568 mpeg->pali = 0;
1569 break;
1570 case GO7007_FORMAT_MPEG2:
1571 mpeg->mpeg_video_standard = GO7007_MPEG_VIDEO_MPEG2;
1572 mpeg->pali = GO7007_MPEG_PROFILE(2, go->pali);
1573 break;
1574 case GO7007_FORMAT_MPEG4:
1575 mpeg->mpeg_video_standard = GO7007_MPEG_VIDEO_MPEG4;
1576 mpeg->pali = GO7007_MPEG_PROFILE(4, go->pali);
1577 break;
1578 default:
1579 return -EINVAL;
1580 }
1581 if (!go->gop_header_enable)
1582 mpeg->flags |= GO7007_MPEG_OMIT_GOP_HEADER;
1583 if (go->repeat_seqhead)
1584 mpeg->flags |= GO7007_MPEG_REPEAT_SEQHEADER;
1585 if (go->dvd_mode)
1586 mpeg->flags |= GO7007_MPEG_FORCE_DVD_MODE;
1587 return 0;
1588 }
1589 case GO7007IOC_S_MD_PARAMS:
1590 {
1591 struct go7007_md_params *mdp = arg;
1592
1593 if (mdp->region > 3)
1594 return -EINVAL;
1595 if (mdp->trigger > 0) {
1596 go->modet[mdp->region].pixel_threshold =
1597 mdp->pixel_threshold >> 1;
1598 go->modet[mdp->region].motion_threshold =
1599 mdp->motion_threshold >> 1;
1600 go->modet[mdp->region].mb_threshold =
1601 mdp->trigger >> 1;
1602 go->modet[mdp->region].enable = 1;
1603 } else
1604 go->modet[mdp->region].enable = 0;
1605
1606 }
1607 case GO7007IOC_G_MD_PARAMS:
1608 {
1609 struct go7007_md_params *mdp = arg;
1610 int region = mdp->region;
1611
1612 if (mdp->region > 3)
1613 return -EINVAL;
1614 memset(mdp, 0, sizeof(struct go7007_md_params));
1615 mdp->region = region;
1616 if (!go->modet[region].enable)
1617 return 0;
1618 mdp->pixel_threshold =
1619 (go->modet[region].pixel_threshold << 1) + 1;
1620 mdp->motion_threshold =
1621 (go->modet[region].motion_threshold << 1) + 1;
1622 mdp->trigger =
1623 (go->modet[region].mb_threshold << 1) + 1;
1624 return 0;
1625 }
1626 case GO7007IOC_S_MD_REGION:
1627 {
1628 struct go7007_md_region *region = arg;
1629
1630 if (region->region < 1 || region->region > 3)
1631 return -EINVAL;
1632 return clip_to_modet_map(go, region->region, region->clips);
1633 }
1634#endif
1635
1636static ssize_t go7007_read(struct file *file, char __user *data,
1637 size_t count, loff_t *ppos)
1638{
1639 return -EINVAL;
1640}
1641
1642static void go7007_vm_open(struct vm_area_struct *vma)
1643{
1644 struct go7007_buffer *gobuf = vma->vm_private_data;
1645
1646 ++gobuf->mapped;
1647}
1648
1649static void go7007_vm_close(struct vm_area_struct *vma)
1650{
1651 struct go7007_buffer *gobuf = vma->vm_private_data;
1652 unsigned long flags;
1653
1654 if (--gobuf->mapped == 0) {
1655 spin_lock_irqsave(&gobuf->go->spinlock, flags);
1656 deactivate_buffer(gobuf);
1657 spin_unlock_irqrestore(&gobuf->go->spinlock, flags);
1658 }
1659}
1660
1661
1662static int go7007_vm_fault(struct vm_area_struct *vma, struct vm_fault *vmf)
1663{
1664 struct page *page;
1665
1666 page = alloc_page(GFP_USER | __GFP_DMA32);
1667 if (!page)
1668 return VM_FAULT_OOM;
1669 clear_user_highpage(page, (unsigned long)vmf->virtual_address);
1670 vmf->page = page;
1671 return 0;
1672}
1673
1674static struct vm_operations_struct go7007_vm_ops = {
1675 .open = go7007_vm_open,
1676 .close = go7007_vm_close,
1677 .fault = go7007_vm_fault,
1678};
1679
1680static int go7007_mmap(struct file *file, struct vm_area_struct *vma)
1681{
1682 struct go7007_file *gofh = file->private_data;
1683 unsigned int index;
1684
1685 if (gofh->go->status != STATUS_ONLINE)
1686 return -EIO;
1687 if (!(vma->vm_flags & VM_SHARED))
1688 return -EINVAL;
1689 if (vma->vm_end - vma->vm_start != GO7007_BUF_SIZE)
1690 return -EINVAL;
1691 mutex_lock(&gofh->lock);
1692 index = vma->vm_pgoff / GO7007_BUF_PAGES;
1693 if (index >= gofh->buf_count) {
1694 mutex_unlock(&gofh->lock);
1695 return -EINVAL;
1696 }
1697 if (index * GO7007_BUF_PAGES != vma->vm_pgoff) {
1698 mutex_unlock(&gofh->lock);
1699 return -EINVAL;
1700 }
1701 if (gofh->bufs[index].mapped > 0) {
1702 mutex_unlock(&gofh->lock);
1703 return -EBUSY;
1704 }
1705 gofh->bufs[index].mapped = 1;
1706 gofh->bufs[index].user_addr = vma->vm_start;
1707 vma->vm_ops = &go7007_vm_ops;
1708 vma->vm_flags |= VM_DONTEXPAND;
1709 vma->vm_flags &= ~VM_IO;
1710 vma->vm_private_data = &gofh->bufs[index];
1711 mutex_unlock(&gofh->lock);
1712 return 0;
1713}
1714
1715static unsigned int go7007_poll(struct file *file, poll_table *wait)
1716{
1717 struct go7007_file *gofh = file->private_data;
1718 struct go7007_buffer *gobuf;
1719
1720 if (list_empty(&gofh->go->stream))
1721 return POLLERR;
1722 gobuf = list_entry(gofh->go->stream.next, struct go7007_buffer, stream);
1723 poll_wait(file, &gofh->go->frame_waitq, wait);
1724 if (gobuf->state == BUF_STATE_DONE)
1725 return POLLIN | POLLRDNORM;
1726 return 0;
1727}
1728
1729static void go7007_vfl_release(struct video_device *vfd)
1730{
1731 struct go7007 *go = video_get_drvdata(vfd);
1732
1733 video_device_release(vfd);
1734 if (--go->ref_count == 0)
1735 kfree(go);
1736}
1737
1738static struct v4l2_file_operations go7007_fops = {
1739 .owner = THIS_MODULE,
1740 .open = go7007_open,
1741 .release = go7007_release,
1742 .ioctl = video_ioctl2,
1743 .read = go7007_read,
1744 .mmap = go7007_mmap,
1745 .poll = go7007_poll,
1746};
1747
1748static const struct v4l2_ioctl_ops video_ioctl_ops = {
1749 .vidioc_querycap = vidioc_querycap,
1750 .vidioc_enum_fmt_vid_cap = vidioc_enum_fmt_vid_cap,
1751 .vidioc_g_fmt_vid_cap = vidioc_g_fmt_vid_cap,
1752 .vidioc_try_fmt_vid_cap = vidioc_try_fmt_vid_cap,
1753 .vidioc_s_fmt_vid_cap = vidioc_s_fmt_vid_cap,
1754 .vidioc_reqbufs = vidioc_reqbufs,
1755 .vidioc_querybuf = vidioc_querybuf,
1756 .vidioc_qbuf = vidioc_qbuf,
1757 .vidioc_dqbuf = vidioc_dqbuf,
1758 .vidioc_g_std = vidioc_g_std,
1759 .vidioc_s_std = vidioc_s_std,
1760 .vidioc_querystd = vidioc_querystd,
1761 .vidioc_enum_input = vidioc_enum_input,
1762 .vidioc_g_input = vidioc_g_input,
1763 .vidioc_s_input = vidioc_s_input,
1764 .vidioc_queryctrl = vidioc_queryctrl,
1765 .vidioc_g_ctrl = vidioc_g_ctrl,
1766 .vidioc_s_ctrl = vidioc_s_ctrl,
1767 .vidioc_streamon = vidioc_streamon,
1768 .vidioc_streamoff = vidioc_streamoff,
1769 .vidioc_g_tuner = vidioc_g_tuner,
1770 .vidioc_s_tuner = vidioc_s_tuner,
1771 .vidioc_g_frequency = vidioc_g_frequency,
1772 .vidioc_s_frequency = vidioc_s_frequency,
1773 .vidioc_g_parm = vidioc_g_parm,
1774 .vidioc_s_parm = vidioc_s_parm,
1775 .vidioc_enum_framesizes = vidioc_enum_framesizes,
1776 .vidioc_enum_frameintervals = vidioc_enum_frameintervals,
1777 .vidioc_cropcap = vidioc_cropcap,
1778 .vidioc_g_crop = vidioc_g_crop,
1779 .vidioc_s_crop = vidioc_s_crop,
1780 .vidioc_g_jpegcomp = vidioc_g_jpegcomp,
1781 .vidioc_s_jpegcomp = vidioc_s_jpegcomp,
1782};
1783
1784static struct video_device go7007_template = {
1785 .name = "go7007",
1786 .fops = &go7007_fops,
1787 .release = go7007_vfl_release,
1788 .ioctl_ops = &video_ioctl_ops,
1789 .tvnorms = V4L2_STD_ALL,
1790 .current_norm = V4L2_STD_NTSC,
1791};
1792
1793int go7007_v4l2_init(struct go7007 *go)
1794{
1795 int rv;
1796
1797 go->video_dev = video_device_alloc();
1798 if (go->video_dev == NULL)
1799 return -ENOMEM;
1800 *go->video_dev = go7007_template;
1801 go->video_dev->parent = go->dev;
1802 rv = video_register_device(go->video_dev, VFL_TYPE_GRABBER, -1);
1803 if (rv < 0) {
1804 video_device_release(go->video_dev);
1805 go->video_dev = NULL;
1806 return rv;
1807 }
1808 rv = v4l2_device_register(go->dev, &go->v4l2_dev);
1809 if (rv < 0) {
1810 video_device_release(go->video_dev);
1811 go->video_dev = NULL;
1812 return rv;
1813 }
1814 video_set_drvdata(go->video_dev, go);
1815 ++go->ref_count;
1816 dev_info(go->dev, "registered device %s [v4l2]\n",
1817 video_device_node_name(go->video_dev));
1818
1819 return 0;
1820}
1821
1822void go7007_v4l2_remove(struct go7007 *go)
1823{
1824 unsigned long flags;
1825
1826 mutex_lock(&go->hw_lock);
1827 if (go->streaming) {
1828 go->streaming = 0;
1829 go7007_stream_stop(go);
1830 spin_lock_irqsave(&go->spinlock, flags);
1831 abort_queued(go);
1832 spin_unlock_irqrestore(&go->spinlock, flags);
1833 }
1834 mutex_unlock(&go->hw_lock);
1835 if (go->video_dev)
1836 video_unregister_device(go->video_dev);
1837 if (go->status != STATUS_SHUTDOWN)
1838 v4l2_device_unregister(&go->v4l2_dev);
1839}
1840