1
2
3
4
5
6
7
8
9
10
11
12
13
14#include <linux/module.h>
15#include <linux/delay.h>
16#include <linux/sched.h>
17#include <linux/spinlock.h>
18#include <linux/slab.h>
19#include <linux/fs.h>
20#include <linux/unistd.h>
21#include <linux/time.h>
22#include <linux/vmalloc.h>
23#include <linux/pagemap.h>
24#include <linux/i2c.h>
25#include <linux/mutex.h>
26#include <linux/uaccess.h>
27#include <linux/videodev2.h>
28#include <media/v4l2-common.h>
29#include <media/v4l2-ioctl.h>
30#include <media/v4l2-subdev.h>
31#include <media/v4l2-event.h>
32#include <media/videobuf2-vmalloc.h>
33#include <media/i2c/saa7115.h>
34
35#include "go7007-priv.h"
36
37#define call_all(dev, o, f, args...) \
38 v4l2_device_call_until_err(dev, 0, o, f, ##args)
39
40static bool valid_pixelformat(u32 pixelformat)
41{
42 switch (pixelformat) {
43 case V4L2_PIX_FMT_MJPEG:
44 case V4L2_PIX_FMT_MPEG1:
45 case V4L2_PIX_FMT_MPEG2:
46 case V4L2_PIX_FMT_MPEG4:
47 return true;
48 default:
49 return false;
50 }
51}
52
53static u32 get_frame_type_flag(struct go7007_buffer *vb, int format)
54{
55 u8 *ptr = vb2_plane_vaddr(&vb->vb.vb2_buf, 0);
56
57 switch (format) {
58 case V4L2_PIX_FMT_MJPEG:
59 return V4L2_BUF_FLAG_KEYFRAME;
60 case V4L2_PIX_FMT_MPEG4:
61 switch ((ptr[vb->frame_offset + 4] >> 6) & 0x3) {
62 case 0:
63 return V4L2_BUF_FLAG_KEYFRAME;
64 case 1:
65 return V4L2_BUF_FLAG_PFRAME;
66 case 2:
67 return V4L2_BUF_FLAG_BFRAME;
68 default:
69 return 0;
70 }
71 case V4L2_PIX_FMT_MPEG1:
72 case V4L2_PIX_FMT_MPEG2:
73 switch ((ptr[vb->frame_offset + 5] >> 3) & 0x7) {
74 case 1:
75 return V4L2_BUF_FLAG_KEYFRAME;
76 case 2:
77 return V4L2_BUF_FLAG_PFRAME;
78 case 3:
79 return V4L2_BUF_FLAG_BFRAME;
80 default:
81 return 0;
82 }
83 }
84
85 return 0;
86}
87
88static void get_resolution(struct go7007 *go, int *width, int *height)
89{
90 switch (go->standard) {
91 case GO7007_STD_NTSC:
92 *width = 720;
93 *height = 480;
94 break;
95 case GO7007_STD_PAL:
96 *width = 720;
97 *height = 576;
98 break;
99 case GO7007_STD_OTHER:
100 default:
101 *width = go->board_info->sensor_width;
102 *height = go->board_info->sensor_height;
103 break;
104 }
105}
106
107static void set_formatting(struct go7007 *go)
108{
109 if (go->format == V4L2_PIX_FMT_MJPEG) {
110 go->pali = 0;
111 go->aspect_ratio = GO7007_RATIO_1_1;
112 go->gop_size = 0;
113 go->ipb = 0;
114 go->closed_gop = 0;
115 go->repeat_seqhead = 0;
116 go->seq_header_enable = 0;
117 go->gop_header_enable = 0;
118 go->dvd_mode = 0;
119 return;
120 }
121
122 switch (go->format) {
123 case V4L2_PIX_FMT_MPEG1:
124 go->pali = 0;
125 break;
126 default:
127 case V4L2_PIX_FMT_MPEG2:
128 go->pali = 0x48;
129 break;
130 case V4L2_PIX_FMT_MPEG4:
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152 go->pali = 0xf5;
153 break;
154 }
155 go->gop_size = v4l2_ctrl_g_ctrl(go->mpeg_video_gop_size);
156 go->closed_gop = v4l2_ctrl_g_ctrl(go->mpeg_video_gop_closure);
157 go->ipb = v4l2_ctrl_g_ctrl(go->mpeg_video_b_frames) != 0;
158 go->bitrate = v4l2_ctrl_g_ctrl(go->mpeg_video_bitrate);
159 go->repeat_seqhead = v4l2_ctrl_g_ctrl(go->mpeg_video_rep_seqheader);
160 go->gop_header_enable = 1;
161 go->dvd_mode = 0;
162 if (go->format == V4L2_PIX_FMT_MPEG2)
163 go->dvd_mode =
164 go->bitrate == 9800000 &&
165 go->gop_size == 15 &&
166 go->ipb == 0 &&
167 go->repeat_seqhead == 1 &&
168 go->closed_gop;
169
170 switch (v4l2_ctrl_g_ctrl(go->mpeg_video_aspect_ratio)) {
171 default:
172 case V4L2_MPEG_VIDEO_ASPECT_1x1:
173 go->aspect_ratio = GO7007_RATIO_1_1;
174 break;
175 case V4L2_MPEG_VIDEO_ASPECT_4x3:
176 go->aspect_ratio = GO7007_RATIO_4_3;
177 break;
178 case V4L2_MPEG_VIDEO_ASPECT_16x9:
179 go->aspect_ratio = GO7007_RATIO_16_9;
180 break;
181 }
182}
183
184static int set_capture_size(struct go7007 *go, struct v4l2_format *fmt, int try)
185{
186 int sensor_height = 0, sensor_width = 0;
187 int width, height;
188
189 if (fmt != NULL && !valid_pixelformat(fmt->fmt.pix.pixelformat))
190 return -EINVAL;
191
192 get_resolution(go, &sensor_width, &sensor_height);
193
194 if (fmt == NULL) {
195 width = sensor_width;
196 height = sensor_height;
197 } else if (go->board_info->sensor_flags & GO7007_SENSOR_SCALING) {
198 if (fmt->fmt.pix.width > sensor_width)
199 width = sensor_width;
200 else if (fmt->fmt.pix.width < 144)
201 width = 144;
202 else
203 width = fmt->fmt.pix.width & ~0x0f;
204
205 if (fmt->fmt.pix.height > sensor_height)
206 height = sensor_height;
207 else if (fmt->fmt.pix.height < 96)
208 height = 96;
209 else
210 height = fmt->fmt.pix.height & ~0x0f;
211 } else {
212 width = fmt->fmt.pix.width;
213
214 if (width <= sensor_width / 4) {
215 width = sensor_width / 4;
216 height = sensor_height / 4;
217 } else if (width <= sensor_width / 2) {
218 width = sensor_width / 2;
219 height = sensor_height / 2;
220 } else {
221 width = sensor_width;
222 height = sensor_height;
223 }
224 width &= ~0xf;
225 height &= ~0xf;
226 }
227
228 if (fmt != NULL) {
229 u32 pixelformat = fmt->fmt.pix.pixelformat;
230
231 memset(fmt, 0, sizeof(*fmt));
232 fmt->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
233 fmt->fmt.pix.width = width;
234 fmt->fmt.pix.height = height;
235 fmt->fmt.pix.pixelformat = pixelformat;
236 fmt->fmt.pix.field = V4L2_FIELD_NONE;
237 fmt->fmt.pix.bytesperline = 0;
238 fmt->fmt.pix.sizeimage = GO7007_BUF_SIZE;
239 fmt->fmt.pix.colorspace = V4L2_COLORSPACE_SMPTE170M;
240 }
241
242 if (try)
243 return 0;
244
245 if (fmt)
246 go->format = fmt->fmt.pix.pixelformat;
247 go->width = width;
248 go->height = height;
249 go->encoder_h_offset = go->board_info->sensor_h_offset;
250 go->encoder_v_offset = go->board_info->sensor_v_offset;
251
252 if (go->board_info->sensor_flags & GO7007_SENSOR_SCALING) {
253 struct v4l2_subdev_format format = {
254 .which = V4L2_SUBDEV_FORMAT_ACTIVE,
255 };
256
257 format.format.code = MEDIA_BUS_FMT_FIXED;
258 format.format.width = fmt ? fmt->fmt.pix.width : width;
259 format.format.height = height;
260 go->encoder_h_halve = 0;
261 go->encoder_v_halve = 0;
262 go->encoder_subsample = 0;
263 call_all(&go->v4l2_dev, pad, set_fmt, NULL, &format);
264 } else {
265 if (width <= sensor_width / 4) {
266 go->encoder_h_halve = 1;
267 go->encoder_v_halve = 1;
268 go->encoder_subsample = 1;
269 } else if (width <= sensor_width / 2) {
270 go->encoder_h_halve = 1;
271 go->encoder_v_halve = 1;
272 go->encoder_subsample = 0;
273 } else {
274 go->encoder_h_halve = 0;
275 go->encoder_v_halve = 0;
276 go->encoder_subsample = 0;
277 }
278 }
279 return 0;
280}
281
282static int vidioc_querycap(struct file *file, void *priv,
283 struct v4l2_capability *cap)
284{
285 struct go7007 *go = video_drvdata(file);
286
287 strlcpy(cap->driver, "go7007", sizeof(cap->driver));
288 strlcpy(cap->card, go->name, sizeof(cap->card));
289 strlcpy(cap->bus_info, go->bus_info, sizeof(cap->bus_info));
290
291 cap->device_caps = V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_READWRITE |
292 V4L2_CAP_STREAMING;
293
294 if (go->board_info->num_aud_inputs)
295 cap->device_caps |= V4L2_CAP_AUDIO;
296 if (go->board_info->flags & GO7007_BOARD_HAS_TUNER)
297 cap->device_caps |= V4L2_CAP_TUNER;
298 cap->capabilities = cap->device_caps | V4L2_CAP_DEVICE_CAPS;
299 return 0;
300}
301
302static int vidioc_enum_fmt_vid_cap(struct file *file, void *priv,
303 struct v4l2_fmtdesc *fmt)
304{
305 char *desc = NULL;
306
307 switch (fmt->index) {
308 case 0:
309 fmt->pixelformat = V4L2_PIX_FMT_MJPEG;
310 desc = "Motion JPEG";
311 break;
312 case 1:
313 fmt->pixelformat = V4L2_PIX_FMT_MPEG1;
314 desc = "MPEG-1 ES";
315 break;
316 case 2:
317 fmt->pixelformat = V4L2_PIX_FMT_MPEG2;
318 desc = "MPEG-2 ES";
319 break;
320 case 3:
321 fmt->pixelformat = V4L2_PIX_FMT_MPEG4;
322 desc = "MPEG-4 ES";
323 break;
324 default:
325 return -EINVAL;
326 }
327 fmt->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
328 fmt->flags = V4L2_FMT_FLAG_COMPRESSED;
329
330 strncpy(fmt->description, desc, sizeof(fmt->description));
331
332 return 0;
333}
334
335static int vidioc_g_fmt_vid_cap(struct file *file, void *priv,
336 struct v4l2_format *fmt)
337{
338 struct go7007 *go = video_drvdata(file);
339
340 fmt->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
341 fmt->fmt.pix.width = go->width;
342 fmt->fmt.pix.height = go->height;
343 fmt->fmt.pix.pixelformat = go->format;
344 fmt->fmt.pix.field = V4L2_FIELD_NONE;
345 fmt->fmt.pix.bytesperline = 0;
346 fmt->fmt.pix.sizeimage = GO7007_BUF_SIZE;
347 fmt->fmt.pix.colorspace = V4L2_COLORSPACE_SMPTE170M;
348
349 return 0;
350}
351
352static int vidioc_try_fmt_vid_cap(struct file *file, void *priv,
353 struct v4l2_format *fmt)
354{
355 struct go7007 *go = video_drvdata(file);
356
357 return set_capture_size(go, fmt, 1);
358}
359
360static int vidioc_s_fmt_vid_cap(struct file *file, void *priv,
361 struct v4l2_format *fmt)
362{
363 struct go7007 *go = video_drvdata(file);
364
365 if (vb2_is_busy(&go->vidq))
366 return -EBUSY;
367
368 return set_capture_size(go, fmt, 0);
369}
370
371static int go7007_queue_setup(struct vb2_queue *q,
372 unsigned int *num_buffers, unsigned int *num_planes,
373 unsigned int sizes[], struct device *alloc_devs[])
374{
375 sizes[0] = GO7007_BUF_SIZE;
376 *num_planes = 1;
377
378 if (*num_buffers < 2)
379 *num_buffers = 2;
380
381 return 0;
382}
383
384static void go7007_buf_queue(struct vb2_buffer *vb)
385{
386 struct vb2_queue *vq = vb->vb2_queue;
387 struct go7007 *go = vb2_get_drv_priv(vq);
388 struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb);
389 struct go7007_buffer *go7007_vb =
390 container_of(vbuf, struct go7007_buffer, vb);
391 unsigned long flags;
392
393 spin_lock_irqsave(&go->spinlock, flags);
394 list_add_tail(&go7007_vb->list, &go->vidq_active);
395 spin_unlock_irqrestore(&go->spinlock, flags);
396}
397
398static int go7007_buf_prepare(struct vb2_buffer *vb)
399{
400 struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb);
401 struct go7007_buffer *go7007_vb =
402 container_of(vbuf, struct go7007_buffer, vb);
403
404 go7007_vb->modet_active = 0;
405 go7007_vb->frame_offset = 0;
406 vb->planes[0].bytesused = 0;
407 return 0;
408}
409
410static void go7007_buf_finish(struct vb2_buffer *vb)
411{
412 struct vb2_queue *vq = vb->vb2_queue;
413 struct go7007 *go = vb2_get_drv_priv(vq);
414 struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb);
415 struct go7007_buffer *go7007_vb =
416 container_of(vbuf, struct go7007_buffer, vb);
417 u32 frame_type_flag = get_frame_type_flag(go7007_vb, go->format);
418
419 vbuf->flags &= ~(V4L2_BUF_FLAG_KEYFRAME | V4L2_BUF_FLAG_BFRAME |
420 V4L2_BUF_FLAG_PFRAME);
421 vbuf->flags |= frame_type_flag;
422 vbuf->field = V4L2_FIELD_NONE;
423}
424
425static int go7007_start_streaming(struct vb2_queue *q, unsigned int count)
426{
427 struct go7007 *go = vb2_get_drv_priv(q);
428 int ret;
429
430 set_formatting(go);
431 mutex_lock(&go->hw_lock);
432 go->next_seq = 0;
433 go->active_buf = NULL;
434 go->modet_event_status = 0;
435 q->streaming = 1;
436 if (go7007_start_encoder(go) < 0)
437 ret = -EIO;
438 else
439 ret = 0;
440 mutex_unlock(&go->hw_lock);
441 if (ret) {
442 q->streaming = 0;
443 return ret;
444 }
445 call_all(&go->v4l2_dev, video, s_stream, 1);
446 v4l2_ctrl_grab(go->mpeg_video_gop_size, true);
447 v4l2_ctrl_grab(go->mpeg_video_gop_closure, true);
448 v4l2_ctrl_grab(go->mpeg_video_bitrate, true);
449 v4l2_ctrl_grab(go->mpeg_video_aspect_ratio, true);
450
451 if (go->board_id == GO7007_BOARDID_ADS_USBAV_709)
452 go7007_write_addr(go, 0x3c82, 0x0005);
453 return ret;
454}
455
456static void go7007_stop_streaming(struct vb2_queue *q)
457{
458 struct go7007 *go = vb2_get_drv_priv(q);
459 unsigned long flags;
460
461 q->streaming = 0;
462 go7007_stream_stop(go);
463 mutex_lock(&go->hw_lock);
464 go7007_reset_encoder(go);
465 mutex_unlock(&go->hw_lock);
466 call_all(&go->v4l2_dev, video, s_stream, 0);
467
468 spin_lock_irqsave(&go->spinlock, flags);
469 INIT_LIST_HEAD(&go->vidq_active);
470 spin_unlock_irqrestore(&go->spinlock, flags);
471 v4l2_ctrl_grab(go->mpeg_video_gop_size, false);
472 v4l2_ctrl_grab(go->mpeg_video_gop_closure, false);
473 v4l2_ctrl_grab(go->mpeg_video_bitrate, false);
474 v4l2_ctrl_grab(go->mpeg_video_aspect_ratio, false);
475
476 if (go->board_id == GO7007_BOARDID_ADS_USBAV_709)
477 go7007_write_addr(go, 0x3c82, 0x000d);
478}
479
480static const struct vb2_ops go7007_video_qops = {
481 .queue_setup = go7007_queue_setup,
482 .buf_queue = go7007_buf_queue,
483 .buf_prepare = go7007_buf_prepare,
484 .buf_finish = go7007_buf_finish,
485 .start_streaming = go7007_start_streaming,
486 .stop_streaming = go7007_stop_streaming,
487 .wait_prepare = vb2_ops_wait_prepare,
488 .wait_finish = vb2_ops_wait_finish,
489};
490
491static int vidioc_g_parm(struct file *filp, void *priv,
492 struct v4l2_streamparm *parm)
493{
494 struct go7007 *go = video_drvdata(filp);
495 struct v4l2_fract timeperframe = {
496 .numerator = 1001 * go->fps_scale,
497 .denominator = go->sensor_framerate,
498 };
499
500 if (parm->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
501 return -EINVAL;
502
503 parm->parm.capture.readbuffers = 2;
504 parm->parm.capture.capability = V4L2_CAP_TIMEPERFRAME;
505 parm->parm.capture.timeperframe = timeperframe;
506
507 return 0;
508}
509
510static int vidioc_s_parm(struct file *filp, void *priv,
511 struct v4l2_streamparm *parm)
512{
513 struct go7007 *go = video_drvdata(filp);
514 unsigned int n, d;
515
516 if (parm->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
517 return -EINVAL;
518
519 n = go->sensor_framerate *
520 parm->parm.capture.timeperframe.numerator;
521 d = 1001 * parm->parm.capture.timeperframe.denominator;
522 if (n != 0 && d != 0 && n > d)
523 go->fps_scale = (n + d/2) / d;
524 else
525 go->fps_scale = 1;
526
527 return vidioc_g_parm(filp, priv, parm);
528}
529
530
531
532
533
534
535
536
537
538
539
540static int vidioc_enum_framesizes(struct file *filp, void *priv,
541 struct v4l2_frmsizeenum *fsize)
542{
543 struct go7007 *go = video_drvdata(filp);
544 int width, height;
545
546 if (fsize->index > 2)
547 return -EINVAL;
548
549 if (!valid_pixelformat(fsize->pixel_format))
550 return -EINVAL;
551
552 get_resolution(go, &width, &height);
553 fsize->type = V4L2_FRMSIZE_TYPE_DISCRETE;
554 fsize->discrete.width = (width >> fsize->index) & ~0xf;
555 fsize->discrete.height = (height >> fsize->index) & ~0xf;
556 return 0;
557}
558
559static int vidioc_enum_frameintervals(struct file *filp, void *priv,
560 struct v4l2_frmivalenum *fival)
561{
562 struct go7007 *go = video_drvdata(filp);
563 int width, height;
564 int i;
565
566 if (fival->index > 4)
567 return -EINVAL;
568
569 if (!valid_pixelformat(fival->pixel_format))
570 return -EINVAL;
571
572 if (!(go->board_info->sensor_flags & GO7007_SENSOR_SCALING)) {
573 get_resolution(go, &width, &height);
574 for (i = 0; i <= 2; i++)
575 if (fival->width == ((width >> i) & ~0xf) &&
576 fival->height == ((height >> i) & ~0xf))
577 break;
578 if (i > 2)
579 return -EINVAL;
580 }
581 fival->type = V4L2_FRMIVAL_TYPE_DISCRETE;
582 fival->discrete.numerator = 1001 * (fival->index + 1);
583 fival->discrete.denominator = go->sensor_framerate;
584 return 0;
585}
586
587static int vidioc_g_std(struct file *file, void *priv, v4l2_std_id *std)
588{
589 struct go7007 *go = video_drvdata(file);
590
591 *std = go->std;
592 return 0;
593}
594
595static int go7007_s_std(struct go7007 *go)
596{
597 if (go->std & V4L2_STD_625_50) {
598 go->standard = GO7007_STD_PAL;
599 go->sensor_framerate = 25025;
600 } else {
601 go->standard = GO7007_STD_NTSC;
602 go->sensor_framerate = 30000;
603 }
604
605 call_all(&go->v4l2_dev, video, s_std, go->std);
606 set_capture_size(go, NULL, 0);
607 return 0;
608}
609
610static int vidioc_s_std(struct file *file, void *priv, v4l2_std_id std)
611{
612 struct go7007 *go = video_drvdata(file);
613
614 if (vb2_is_busy(&go->vidq))
615 return -EBUSY;
616
617 go->std = std;
618
619 return go7007_s_std(go);
620}
621
622static int vidioc_querystd(struct file *file, void *priv, v4l2_std_id *std)
623{
624 struct go7007 *go = video_drvdata(file);
625
626 return call_all(&go->v4l2_dev, video, querystd, std);
627}
628
629static int vidioc_enum_input(struct file *file, void *priv,
630 struct v4l2_input *inp)
631{
632 struct go7007 *go = video_drvdata(file);
633
634 if (inp->index >= go->board_info->num_inputs)
635 return -EINVAL;
636
637 strncpy(inp->name, go->board_info->inputs[inp->index].name,
638 sizeof(inp->name));
639
640
641 if ((go->board_info->flags & GO7007_BOARD_HAS_TUNER) &&
642 inp->index == 0)
643 inp->type = V4L2_INPUT_TYPE_TUNER;
644 else
645 inp->type = V4L2_INPUT_TYPE_CAMERA;
646
647 if (go->board_info->num_aud_inputs)
648 inp->audioset = (1 << go->board_info->num_aud_inputs) - 1;
649 else
650 inp->audioset = 0;
651 inp->tuner = 0;
652 if (go->board_info->sensor_flags & GO7007_SENSOR_TV)
653 inp->std = video_devdata(file)->tvnorms;
654 else
655 inp->std = 0;
656
657 return 0;
658}
659
660
661static int vidioc_g_input(struct file *file, void *priv, unsigned int *input)
662{
663 struct go7007 *go = video_drvdata(file);
664
665 *input = go->input;
666
667 return 0;
668}
669
670static int vidioc_enumaudio(struct file *file, void *fh, struct v4l2_audio *a)
671{
672 struct go7007 *go = video_drvdata(file);
673
674 if (a->index >= go->board_info->num_aud_inputs)
675 return -EINVAL;
676 strlcpy(a->name, go->board_info->aud_inputs[a->index].name,
677 sizeof(a->name));
678 a->capability = V4L2_AUDCAP_STEREO;
679 return 0;
680}
681
682static int vidioc_g_audio(struct file *file, void *fh, struct v4l2_audio *a)
683{
684 struct go7007 *go = video_drvdata(file);
685
686 a->index = go->aud_input;
687 strlcpy(a->name, go->board_info->aud_inputs[go->aud_input].name,
688 sizeof(a->name));
689 a->capability = V4L2_AUDCAP_STEREO;
690 return 0;
691}
692
693static int vidioc_s_audio(struct file *file, void *fh,
694 const struct v4l2_audio *a)
695{
696 struct go7007 *go = video_drvdata(file);
697
698 if (a->index >= go->board_info->num_aud_inputs)
699 return -EINVAL;
700 go->aud_input = a->index;
701 v4l2_subdev_call(go->sd_audio, audio, s_routing,
702 go->board_info->aud_inputs[go->aud_input].audio_input, 0, 0);
703 return 0;
704}
705
706static void go7007_s_input(struct go7007 *go)
707{
708 unsigned int input = go->input;
709
710 v4l2_subdev_call(go->sd_video, video, s_routing,
711 go->board_info->inputs[input].video_input, 0,
712 go->board_info->video_config);
713 if (go->board_info->num_aud_inputs) {
714 int aud_input = go->board_info->inputs[input].audio_index;
715
716 v4l2_subdev_call(go->sd_audio, audio, s_routing,
717 go->board_info->aud_inputs[aud_input].audio_input, 0, 0);
718 go->aud_input = aud_input;
719 }
720}
721
722static int vidioc_s_input(struct file *file, void *priv, unsigned int input)
723{
724 struct go7007 *go = video_drvdata(file);
725
726 if (input >= go->board_info->num_inputs)
727 return -EINVAL;
728 if (vb2_is_busy(&go->vidq))
729 return -EBUSY;
730
731 go->input = input;
732 go7007_s_input(go);
733
734 return 0;
735}
736
737static int vidioc_g_tuner(struct file *file, void *priv,
738 struct v4l2_tuner *t)
739{
740 struct go7007 *go = video_drvdata(file);
741
742 if (t->index != 0)
743 return -EINVAL;
744
745 strlcpy(t->name, "Tuner", sizeof(t->name));
746 return call_all(&go->v4l2_dev, tuner, g_tuner, t);
747}
748
749static int vidioc_s_tuner(struct file *file, void *priv,
750 const struct v4l2_tuner *t)
751{
752 struct go7007 *go = video_drvdata(file);
753
754 if (t->index != 0)
755 return -EINVAL;
756
757 return call_all(&go->v4l2_dev, tuner, s_tuner, t);
758}
759
760static int vidioc_g_frequency(struct file *file, void *priv,
761 struct v4l2_frequency *f)
762{
763 struct go7007 *go = video_drvdata(file);
764
765 if (f->tuner)
766 return -EINVAL;
767
768 return call_all(&go->v4l2_dev, tuner, g_frequency, f);
769}
770
771static int vidioc_s_frequency(struct file *file, void *priv,
772 const struct v4l2_frequency *f)
773{
774 struct go7007 *go = video_drvdata(file);
775
776 if (f->tuner)
777 return -EINVAL;
778
779 return call_all(&go->v4l2_dev, tuner, s_frequency, f);
780}
781
782static int vidioc_log_status(struct file *file, void *priv)
783{
784 struct go7007 *go = video_drvdata(file);
785
786 v4l2_ctrl_log_status(file, priv);
787 return call_all(&go->v4l2_dev, core, log_status);
788}
789
790static int vidioc_subscribe_event(struct v4l2_fh *fh,
791 const struct v4l2_event_subscription *sub)
792{
793
794 switch (sub->type) {
795 case V4L2_EVENT_MOTION_DET:
796
797
798 return v4l2_event_subscribe(fh, sub, 30, NULL);
799 default:
800 return v4l2_ctrl_subscribe_event(fh, sub);
801 }
802}
803
804
805static int go7007_s_ctrl(struct v4l2_ctrl *ctrl)
806{
807 struct go7007 *go =
808 container_of(ctrl->handler, struct go7007, hdl);
809 unsigned y;
810 u8 *mt;
811
812 switch (ctrl->id) {
813 case V4L2_CID_PIXEL_THRESHOLD0:
814 go->modet[0].pixel_threshold = ctrl->val;
815 break;
816 case V4L2_CID_MOTION_THRESHOLD0:
817 go->modet[0].motion_threshold = ctrl->val;
818 break;
819 case V4L2_CID_MB_THRESHOLD0:
820 go->modet[0].mb_threshold = ctrl->val;
821 break;
822 case V4L2_CID_PIXEL_THRESHOLD1:
823 go->modet[1].pixel_threshold = ctrl->val;
824 break;
825 case V4L2_CID_MOTION_THRESHOLD1:
826 go->modet[1].motion_threshold = ctrl->val;
827 break;
828 case V4L2_CID_MB_THRESHOLD1:
829 go->modet[1].mb_threshold = ctrl->val;
830 break;
831 case V4L2_CID_PIXEL_THRESHOLD2:
832 go->modet[2].pixel_threshold = ctrl->val;
833 break;
834 case V4L2_CID_MOTION_THRESHOLD2:
835 go->modet[2].motion_threshold = ctrl->val;
836 break;
837 case V4L2_CID_MB_THRESHOLD2:
838 go->modet[2].mb_threshold = ctrl->val;
839 break;
840 case V4L2_CID_PIXEL_THRESHOLD3:
841 go->modet[3].pixel_threshold = ctrl->val;
842 break;
843 case V4L2_CID_MOTION_THRESHOLD3:
844 go->modet[3].motion_threshold = ctrl->val;
845 break;
846 case V4L2_CID_MB_THRESHOLD3:
847 go->modet[3].mb_threshold = ctrl->val;
848 break;
849 case V4L2_CID_DETECT_MD_REGION_GRID:
850 mt = go->modet_map;
851 for (y = 0; y < go->height / 16; y++, mt += go->width / 16)
852 memcpy(mt, ctrl->p_new.p_u8 + y * (720 / 16), go->width / 16);
853 break;
854 default:
855 return -EINVAL;
856 }
857 return 0;
858}
859
860static const struct v4l2_file_operations go7007_fops = {
861 .owner = THIS_MODULE,
862 .open = v4l2_fh_open,
863 .release = vb2_fop_release,
864 .unlocked_ioctl = video_ioctl2,
865 .read = vb2_fop_read,
866 .mmap = vb2_fop_mmap,
867 .poll = vb2_fop_poll,
868};
869
870static const struct v4l2_ioctl_ops video_ioctl_ops = {
871 .vidioc_querycap = vidioc_querycap,
872 .vidioc_enum_fmt_vid_cap = vidioc_enum_fmt_vid_cap,
873 .vidioc_g_fmt_vid_cap = vidioc_g_fmt_vid_cap,
874 .vidioc_try_fmt_vid_cap = vidioc_try_fmt_vid_cap,
875 .vidioc_s_fmt_vid_cap = vidioc_s_fmt_vid_cap,
876 .vidioc_reqbufs = vb2_ioctl_reqbufs,
877 .vidioc_querybuf = vb2_ioctl_querybuf,
878 .vidioc_qbuf = vb2_ioctl_qbuf,
879 .vidioc_dqbuf = vb2_ioctl_dqbuf,
880 .vidioc_g_std = vidioc_g_std,
881 .vidioc_s_std = vidioc_s_std,
882 .vidioc_querystd = vidioc_querystd,
883 .vidioc_enum_input = vidioc_enum_input,
884 .vidioc_g_input = vidioc_g_input,
885 .vidioc_s_input = vidioc_s_input,
886 .vidioc_enumaudio = vidioc_enumaudio,
887 .vidioc_g_audio = vidioc_g_audio,
888 .vidioc_s_audio = vidioc_s_audio,
889 .vidioc_streamon = vb2_ioctl_streamon,
890 .vidioc_streamoff = vb2_ioctl_streamoff,
891 .vidioc_g_tuner = vidioc_g_tuner,
892 .vidioc_s_tuner = vidioc_s_tuner,
893 .vidioc_g_frequency = vidioc_g_frequency,
894 .vidioc_s_frequency = vidioc_s_frequency,
895 .vidioc_g_parm = vidioc_g_parm,
896 .vidioc_s_parm = vidioc_s_parm,
897 .vidioc_enum_framesizes = vidioc_enum_framesizes,
898 .vidioc_enum_frameintervals = vidioc_enum_frameintervals,
899 .vidioc_log_status = vidioc_log_status,
900 .vidioc_subscribe_event = vidioc_subscribe_event,
901 .vidioc_unsubscribe_event = v4l2_event_unsubscribe,
902};
903
904static const struct video_device go7007_template = {
905 .name = "go7007",
906 .fops = &go7007_fops,
907 .release = video_device_release_empty,
908 .ioctl_ops = &video_ioctl_ops,
909 .tvnorms = V4L2_STD_ALL,
910};
911
912static const struct v4l2_ctrl_ops go7007_ctrl_ops = {
913 .s_ctrl = go7007_s_ctrl,
914};
915
916static const struct v4l2_ctrl_config go7007_pixel_threshold0_ctrl = {
917 .ops = &go7007_ctrl_ops,
918 .id = V4L2_CID_PIXEL_THRESHOLD0,
919 .name = "Pixel Threshold Region 0",
920 .type = V4L2_CTRL_TYPE_INTEGER,
921 .def = 20,
922 .max = 32767,
923 .step = 1,
924};
925
926static const struct v4l2_ctrl_config go7007_motion_threshold0_ctrl = {
927 .ops = &go7007_ctrl_ops,
928 .id = V4L2_CID_MOTION_THRESHOLD0,
929 .name = "Motion Threshold Region 0",
930 .type = V4L2_CTRL_TYPE_INTEGER,
931 .def = 80,
932 .max = 32767,
933 .step = 1,
934};
935
936static const struct v4l2_ctrl_config go7007_mb_threshold0_ctrl = {
937 .ops = &go7007_ctrl_ops,
938 .id = V4L2_CID_MB_THRESHOLD0,
939 .name = "MB Threshold Region 0",
940 .type = V4L2_CTRL_TYPE_INTEGER,
941 .def = 200,
942 .max = 32767,
943 .step = 1,
944};
945
946static const struct v4l2_ctrl_config go7007_pixel_threshold1_ctrl = {
947 .ops = &go7007_ctrl_ops,
948 .id = V4L2_CID_PIXEL_THRESHOLD1,
949 .name = "Pixel Threshold Region 1",
950 .type = V4L2_CTRL_TYPE_INTEGER,
951 .def = 20,
952 .max = 32767,
953 .step = 1,
954};
955
956static const struct v4l2_ctrl_config go7007_motion_threshold1_ctrl = {
957 .ops = &go7007_ctrl_ops,
958 .id = V4L2_CID_MOTION_THRESHOLD1,
959 .name = "Motion Threshold Region 1",
960 .type = V4L2_CTRL_TYPE_INTEGER,
961 .def = 80,
962 .max = 32767,
963 .step = 1,
964};
965
966static const struct v4l2_ctrl_config go7007_mb_threshold1_ctrl = {
967 .ops = &go7007_ctrl_ops,
968 .id = V4L2_CID_MB_THRESHOLD1,
969 .name = "MB Threshold Region 1",
970 .type = V4L2_CTRL_TYPE_INTEGER,
971 .def = 200,
972 .max = 32767,
973 .step = 1,
974};
975
976static const struct v4l2_ctrl_config go7007_pixel_threshold2_ctrl = {
977 .ops = &go7007_ctrl_ops,
978 .id = V4L2_CID_PIXEL_THRESHOLD2,
979 .name = "Pixel Threshold Region 2",
980 .type = V4L2_CTRL_TYPE_INTEGER,
981 .def = 20,
982 .max = 32767,
983 .step = 1,
984};
985
986static const struct v4l2_ctrl_config go7007_motion_threshold2_ctrl = {
987 .ops = &go7007_ctrl_ops,
988 .id = V4L2_CID_MOTION_THRESHOLD2,
989 .name = "Motion Threshold Region 2",
990 .type = V4L2_CTRL_TYPE_INTEGER,
991 .def = 80,
992 .max = 32767,
993 .step = 1,
994};
995
996static const struct v4l2_ctrl_config go7007_mb_threshold2_ctrl = {
997 .ops = &go7007_ctrl_ops,
998 .id = V4L2_CID_MB_THRESHOLD2,
999 .name = "MB Threshold Region 2",
1000 .type = V4L2_CTRL_TYPE_INTEGER,
1001 .def = 200,
1002 .max = 32767,
1003 .step = 1,
1004};
1005
1006static const struct v4l2_ctrl_config go7007_pixel_threshold3_ctrl = {
1007 .ops = &go7007_ctrl_ops,
1008 .id = V4L2_CID_PIXEL_THRESHOLD3,
1009 .name = "Pixel Threshold Region 3",
1010 .type = V4L2_CTRL_TYPE_INTEGER,
1011 .def = 20,
1012 .max = 32767,
1013 .step = 1,
1014};
1015
1016static const struct v4l2_ctrl_config go7007_motion_threshold3_ctrl = {
1017 .ops = &go7007_ctrl_ops,
1018 .id = V4L2_CID_MOTION_THRESHOLD3,
1019 .name = "Motion Threshold Region 3",
1020 .type = V4L2_CTRL_TYPE_INTEGER,
1021 .def = 80,
1022 .max = 32767,
1023 .step = 1,
1024};
1025
1026static const struct v4l2_ctrl_config go7007_mb_threshold3_ctrl = {
1027 .ops = &go7007_ctrl_ops,
1028 .id = V4L2_CID_MB_THRESHOLD3,
1029 .name = "MB Threshold Region 3",
1030 .type = V4L2_CTRL_TYPE_INTEGER,
1031 .def = 200,
1032 .max = 32767,
1033 .step = 1,
1034};
1035
1036static const struct v4l2_ctrl_config go7007_mb_regions_ctrl = {
1037 .ops = &go7007_ctrl_ops,
1038 .id = V4L2_CID_DETECT_MD_REGION_GRID,
1039 .dims = { 576 / 16, 720 / 16 },
1040 .max = 3,
1041 .step = 1,
1042};
1043
1044int go7007_v4l2_ctrl_init(struct go7007 *go)
1045{
1046 struct v4l2_ctrl_handler *hdl = &go->hdl;
1047 struct v4l2_ctrl *ctrl;
1048
1049 v4l2_ctrl_handler_init(hdl, 22);
1050 go->mpeg_video_gop_size = v4l2_ctrl_new_std(hdl, NULL,
1051 V4L2_CID_MPEG_VIDEO_GOP_SIZE, 0, 34, 1, 15);
1052 go->mpeg_video_gop_closure = v4l2_ctrl_new_std(hdl, NULL,
1053 V4L2_CID_MPEG_VIDEO_GOP_CLOSURE, 0, 1, 1, 1);
1054 go->mpeg_video_bitrate = v4l2_ctrl_new_std(hdl, NULL,
1055 V4L2_CID_MPEG_VIDEO_BITRATE,
1056 64000, 10000000, 1, 9800000);
1057 go->mpeg_video_b_frames = v4l2_ctrl_new_std(hdl, NULL,
1058 V4L2_CID_MPEG_VIDEO_B_FRAMES, 0, 2, 2, 0);
1059 go->mpeg_video_rep_seqheader = v4l2_ctrl_new_std(hdl, NULL,
1060 V4L2_CID_MPEG_VIDEO_REPEAT_SEQ_HEADER, 0, 1, 1, 1);
1061
1062 go->mpeg_video_aspect_ratio = v4l2_ctrl_new_std_menu(hdl, NULL,
1063 V4L2_CID_MPEG_VIDEO_ASPECT,
1064 V4L2_MPEG_VIDEO_ASPECT_16x9, 0,
1065 V4L2_MPEG_VIDEO_ASPECT_1x1);
1066 ctrl = v4l2_ctrl_new_std(hdl, NULL,
1067 V4L2_CID_JPEG_ACTIVE_MARKER, 0,
1068 V4L2_JPEG_ACTIVE_MARKER_DQT |
1069 V4L2_JPEG_ACTIVE_MARKER_DHT, 0,
1070 V4L2_JPEG_ACTIVE_MARKER_DQT |
1071 V4L2_JPEG_ACTIVE_MARKER_DHT);
1072 if (ctrl)
1073 ctrl->flags |= V4L2_CTRL_FLAG_READ_ONLY;
1074 v4l2_ctrl_new_custom(hdl, &go7007_pixel_threshold0_ctrl, NULL);
1075 v4l2_ctrl_new_custom(hdl, &go7007_motion_threshold0_ctrl, NULL);
1076 v4l2_ctrl_new_custom(hdl, &go7007_mb_threshold0_ctrl, NULL);
1077 v4l2_ctrl_new_custom(hdl, &go7007_pixel_threshold1_ctrl, NULL);
1078 v4l2_ctrl_new_custom(hdl, &go7007_motion_threshold1_ctrl, NULL);
1079 v4l2_ctrl_new_custom(hdl, &go7007_mb_threshold1_ctrl, NULL);
1080 v4l2_ctrl_new_custom(hdl, &go7007_pixel_threshold2_ctrl, NULL);
1081 v4l2_ctrl_new_custom(hdl, &go7007_motion_threshold2_ctrl, NULL);
1082 v4l2_ctrl_new_custom(hdl, &go7007_mb_threshold2_ctrl, NULL);
1083 v4l2_ctrl_new_custom(hdl, &go7007_pixel_threshold3_ctrl, NULL);
1084 v4l2_ctrl_new_custom(hdl, &go7007_motion_threshold3_ctrl, NULL);
1085 v4l2_ctrl_new_custom(hdl, &go7007_mb_threshold3_ctrl, NULL);
1086 v4l2_ctrl_new_custom(hdl, &go7007_mb_regions_ctrl, NULL);
1087 go->modet_mode = v4l2_ctrl_new_std_menu(hdl, NULL,
1088 V4L2_CID_DETECT_MD_MODE,
1089 V4L2_DETECT_MD_MODE_REGION_GRID,
1090 1 << V4L2_DETECT_MD_MODE_THRESHOLD_GRID,
1091 V4L2_DETECT_MD_MODE_DISABLED);
1092 if (hdl->error) {
1093 int rv = hdl->error;
1094
1095 v4l2_err(&go->v4l2_dev, "Could not register controls\n");
1096 return rv;
1097 }
1098 go->v4l2_dev.ctrl_handler = hdl;
1099 return 0;
1100}
1101
1102int go7007_v4l2_init(struct go7007 *go)
1103{
1104 struct video_device *vdev = &go->vdev;
1105 int rv;
1106
1107 mutex_init(&go->serialize_lock);
1108 mutex_init(&go->queue_lock);
1109
1110 INIT_LIST_HEAD(&go->vidq_active);
1111 go->vidq.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
1112 go->vidq.io_modes = VB2_MMAP | VB2_USERPTR | VB2_READ;
1113 go->vidq.ops = &go7007_video_qops;
1114 go->vidq.mem_ops = &vb2_vmalloc_memops;
1115 go->vidq.drv_priv = go;
1116 go->vidq.buf_struct_size = sizeof(struct go7007_buffer);
1117 go->vidq.timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_MONOTONIC;
1118 go->vidq.lock = &go->queue_lock;
1119 rv = vb2_queue_init(&go->vidq);
1120 if (rv)
1121 return rv;
1122 *vdev = go7007_template;
1123 vdev->lock = &go->serialize_lock;
1124 vdev->queue = &go->vidq;
1125 video_set_drvdata(vdev, go);
1126 vdev->v4l2_dev = &go->v4l2_dev;
1127 if (!v4l2_device_has_op(&go->v4l2_dev, 0, video, querystd))
1128 v4l2_disable_ioctl(vdev, VIDIOC_QUERYSTD);
1129 if (!(go->board_info->flags & GO7007_BOARD_HAS_TUNER)) {
1130 v4l2_disable_ioctl(vdev, VIDIOC_S_FREQUENCY);
1131 v4l2_disable_ioctl(vdev, VIDIOC_G_FREQUENCY);
1132 v4l2_disable_ioctl(vdev, VIDIOC_S_TUNER);
1133 v4l2_disable_ioctl(vdev, VIDIOC_G_TUNER);
1134 } else {
1135 struct v4l2_frequency f = {
1136 .type = V4L2_TUNER_ANALOG_TV,
1137 .frequency = 980,
1138 };
1139
1140 call_all(&go->v4l2_dev, tuner, s_frequency, &f);
1141 }
1142 if (!(go->board_info->sensor_flags & GO7007_SENSOR_TV)) {
1143 v4l2_disable_ioctl(vdev, VIDIOC_G_STD);
1144 v4l2_disable_ioctl(vdev, VIDIOC_S_STD);
1145 vdev->tvnorms = 0;
1146 }
1147 if (go->board_info->sensor_flags & GO7007_SENSOR_SCALING)
1148 v4l2_disable_ioctl(vdev, VIDIOC_ENUM_FRAMESIZES);
1149 if (go->board_info->num_aud_inputs == 0) {
1150 v4l2_disable_ioctl(vdev, VIDIOC_G_AUDIO);
1151 v4l2_disable_ioctl(vdev, VIDIOC_S_AUDIO);
1152 v4l2_disable_ioctl(vdev, VIDIOC_ENUMAUDIO);
1153 }
1154
1155 if (go->board_info->sensor_flags & GO7007_SENSOR_SAA7115)
1156 v4l2_subdev_call(go->sd_video, video, s_crystal_freq,
1157 SAA7115_FREQ_24_576_MHZ,
1158 SAA7115_FREQ_FL_APLL | SAA7115_FREQ_FL_UCGC |
1159 SAA7115_FREQ_FL_DOUBLE_ASCLK);
1160 go7007_s_input(go);
1161 if (go->board_info->sensor_flags & GO7007_SENSOR_TV)
1162 go7007_s_std(go);
1163 rv = video_register_device(vdev, VFL_TYPE_GRABBER, -1);
1164 if (rv < 0)
1165 return rv;
1166 dev_info(go->dev, "registered device %s [v4l2]\n",
1167 video_device_node_name(vdev));
1168
1169 return 0;
1170}
1171
1172void go7007_v4l2_remove(struct go7007 *go)
1173{
1174 v4l2_ctrl_handler_free(&go->hdl);
1175}
1176