1 /*
2 * Copyright (C) 2005-2006 Micronas USA Inc.
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License (Version 2) as
6 * published by the Free Software Foundation.
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 */
13
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/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
valid_pixelformat(u32 pixelformat)40 static 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
get_frame_type_flag(struct go7007_buffer * vb,int format)53 static u32 get_frame_type_flag(struct go7007_buffer *vb, int format)
54 {
55 u8 *ptr = vb2_plane_vaddr(&vb->vb, 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
get_resolution(struct go7007 * go,int * width,int * height)88 static 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
set_formatting(struct go7007 * go)107 static 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 /* For future reference: this is the list of MPEG4
132 * profiles that are available, although they are
133 * untested:
134 *
135 * Profile pali
136 * -------------- ----
137 * PROFILE_S_L0 0x08
138 * PROFILE_S_L1 0x01
139 * PROFILE_S_L2 0x02
140 * PROFILE_S_L3 0x03
141 * PROFILE_ARTS_L1 0x91
142 * PROFILE_ARTS_L2 0x92
143 * PROFILE_ARTS_L3 0x93
144 * PROFILE_ARTS_L4 0x94
145 * PROFILE_AS_L0 0xf0
146 * PROFILE_AS_L1 0xf1
147 * PROFILE_AS_L2 0xf2
148 * PROFILE_AS_L3 0xf3
149 * PROFILE_AS_L4 0xf4
150 * PROFILE_AS_L5 0xf5
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
set_capture_size(struct go7007 * go,struct v4l2_format * fmt,int try)184 static 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_mbus_framefmt mbus_fmt;
254
255 mbus_fmt.code = MEDIA_BUS_FMT_FIXED;
256 mbus_fmt.width = fmt ? fmt->fmt.pix.width : width;
257 mbus_fmt.height = height;
258 go->encoder_h_halve = 0;
259 go->encoder_v_halve = 0;
260 go->encoder_subsample = 0;
261 call_all(&go->v4l2_dev, video, s_mbus_fmt, &mbus_fmt);
262 } else {
263 if (width <= sensor_width / 4) {
264 go->encoder_h_halve = 1;
265 go->encoder_v_halve = 1;
266 go->encoder_subsample = 1;
267 } else if (width <= sensor_width / 2) {
268 go->encoder_h_halve = 1;
269 go->encoder_v_halve = 1;
270 go->encoder_subsample = 0;
271 } else {
272 go->encoder_h_halve = 0;
273 go->encoder_v_halve = 0;
274 go->encoder_subsample = 0;
275 }
276 }
277 return 0;
278 }
279
vidioc_querycap(struct file * file,void * priv,struct v4l2_capability * cap)280 static int vidioc_querycap(struct file *file, void *priv,
281 struct v4l2_capability *cap)
282 {
283 struct go7007 *go = video_drvdata(file);
284
285 strlcpy(cap->driver, "go7007", sizeof(cap->driver));
286 strlcpy(cap->card, go->name, sizeof(cap->card));
287 strlcpy(cap->bus_info, go->bus_info, sizeof(cap->bus_info));
288
289 cap->device_caps = V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_READWRITE |
290 V4L2_CAP_STREAMING;
291
292 if (go->board_info->num_aud_inputs)
293 cap->device_caps |= V4L2_CAP_AUDIO;
294 if (go->board_info->flags & GO7007_BOARD_HAS_TUNER)
295 cap->device_caps |= V4L2_CAP_TUNER;
296 cap->capabilities = cap->device_caps | V4L2_CAP_DEVICE_CAPS;
297 return 0;
298 }
299
vidioc_enum_fmt_vid_cap(struct file * file,void * priv,struct v4l2_fmtdesc * fmt)300 static int vidioc_enum_fmt_vid_cap(struct file *file, void *priv,
301 struct v4l2_fmtdesc *fmt)
302 {
303 char *desc = NULL;
304
305 switch (fmt->index) {
306 case 0:
307 fmt->pixelformat = V4L2_PIX_FMT_MJPEG;
308 desc = "Motion JPEG";
309 break;
310 case 1:
311 fmt->pixelformat = V4L2_PIX_FMT_MPEG1;
312 desc = "MPEG-1 ES";
313 break;
314 case 2:
315 fmt->pixelformat = V4L2_PIX_FMT_MPEG2;
316 desc = "MPEG-2 ES";
317 break;
318 case 3:
319 fmt->pixelformat = V4L2_PIX_FMT_MPEG4;
320 desc = "MPEG-4 ES";
321 break;
322 default:
323 return -EINVAL;
324 }
325 fmt->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
326 fmt->flags = V4L2_FMT_FLAG_COMPRESSED;
327
328 strncpy(fmt->description, desc, sizeof(fmt->description));
329
330 return 0;
331 }
332
vidioc_g_fmt_vid_cap(struct file * file,void * priv,struct v4l2_format * fmt)333 static int vidioc_g_fmt_vid_cap(struct file *file, void *priv,
334 struct v4l2_format *fmt)
335 {
336 struct go7007 *go = video_drvdata(file);
337
338 fmt->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
339 fmt->fmt.pix.width = go->width;
340 fmt->fmt.pix.height = go->height;
341 fmt->fmt.pix.pixelformat = go->format;
342 fmt->fmt.pix.field = V4L2_FIELD_NONE;
343 fmt->fmt.pix.bytesperline = 0;
344 fmt->fmt.pix.sizeimage = GO7007_BUF_SIZE;
345 fmt->fmt.pix.colorspace = V4L2_COLORSPACE_SMPTE170M;
346
347 return 0;
348 }
349
vidioc_try_fmt_vid_cap(struct file * file,void * priv,struct v4l2_format * fmt)350 static int vidioc_try_fmt_vid_cap(struct file *file, void *priv,
351 struct v4l2_format *fmt)
352 {
353 struct go7007 *go = video_drvdata(file);
354
355 return set_capture_size(go, fmt, 1);
356 }
357
vidioc_s_fmt_vid_cap(struct file * file,void * priv,struct v4l2_format * fmt)358 static int vidioc_s_fmt_vid_cap(struct file *file, void *priv,
359 struct v4l2_format *fmt)
360 {
361 struct go7007 *go = video_drvdata(file);
362
363 if (vb2_is_busy(&go->vidq))
364 return -EBUSY;
365
366 return set_capture_size(go, fmt, 0);
367 }
368
go7007_queue_setup(struct vb2_queue * q,const struct v4l2_format * fmt,unsigned int * num_buffers,unsigned int * num_planes,unsigned int sizes[],void * alloc_ctxs[])369 static int go7007_queue_setup(struct vb2_queue *q,
370 const struct v4l2_format *fmt,
371 unsigned int *num_buffers, unsigned int *num_planes,
372 unsigned int sizes[], void *alloc_ctxs[])
373 {
374 sizes[0] = GO7007_BUF_SIZE;
375 *num_planes = 1;
376
377 if (*num_buffers < 2)
378 *num_buffers = 2;
379
380 return 0;
381 }
382
go7007_buf_queue(struct vb2_buffer * vb)383 static void go7007_buf_queue(struct vb2_buffer *vb)
384 {
385 struct vb2_queue *vq = vb->vb2_queue;
386 struct go7007 *go = vb2_get_drv_priv(vq);
387 struct go7007_buffer *go7007_vb =
388 container_of(vb, struct go7007_buffer, vb);
389 unsigned long flags;
390
391 spin_lock_irqsave(&go->spinlock, flags);
392 list_add_tail(&go7007_vb->list, &go->vidq_active);
393 spin_unlock_irqrestore(&go->spinlock, flags);
394 }
395
go7007_buf_prepare(struct vb2_buffer * vb)396 static int go7007_buf_prepare(struct vb2_buffer *vb)
397 {
398 struct go7007_buffer *go7007_vb =
399 container_of(vb, struct go7007_buffer, vb);
400
401 go7007_vb->modet_active = 0;
402 go7007_vb->frame_offset = 0;
403 vb->v4l2_planes[0].bytesused = 0;
404 return 0;
405 }
406
go7007_buf_finish(struct vb2_buffer * vb)407 static void go7007_buf_finish(struct vb2_buffer *vb)
408 {
409 struct vb2_queue *vq = vb->vb2_queue;
410 struct go7007 *go = vb2_get_drv_priv(vq);
411 struct go7007_buffer *go7007_vb =
412 container_of(vb, struct go7007_buffer, vb);
413 u32 frame_type_flag = get_frame_type_flag(go7007_vb, go->format);
414 struct v4l2_buffer *buf = &vb->v4l2_buf;
415
416 buf->flags &= ~(V4L2_BUF_FLAG_KEYFRAME | V4L2_BUF_FLAG_BFRAME |
417 V4L2_BUF_FLAG_PFRAME);
418 buf->flags |= frame_type_flag;
419 buf->field = V4L2_FIELD_NONE;
420 }
421
go7007_start_streaming(struct vb2_queue * q,unsigned int count)422 static int go7007_start_streaming(struct vb2_queue *q, unsigned int count)
423 {
424 struct go7007 *go = vb2_get_drv_priv(q);
425 int ret;
426
427 set_formatting(go);
428 mutex_lock(&go->hw_lock);
429 go->next_seq = 0;
430 go->active_buf = NULL;
431 go->modet_event_status = 0;
432 q->streaming = 1;
433 if (go7007_start_encoder(go) < 0)
434 ret = -EIO;
435 else
436 ret = 0;
437 mutex_unlock(&go->hw_lock);
438 if (ret) {
439 q->streaming = 0;
440 return ret;
441 }
442 call_all(&go->v4l2_dev, video, s_stream, 1);
443 v4l2_ctrl_grab(go->mpeg_video_gop_size, true);
444 v4l2_ctrl_grab(go->mpeg_video_gop_closure, true);
445 v4l2_ctrl_grab(go->mpeg_video_bitrate, true);
446 v4l2_ctrl_grab(go->mpeg_video_aspect_ratio, true);
447 /* Turn on Capture LED */
448 if (go->board_id == GO7007_BOARDID_ADS_USBAV_709)
449 go7007_write_addr(go, 0x3c82, 0x0005);
450 return ret;
451 }
452
go7007_stop_streaming(struct vb2_queue * q)453 static void go7007_stop_streaming(struct vb2_queue *q)
454 {
455 struct go7007 *go = vb2_get_drv_priv(q);
456 unsigned long flags;
457
458 q->streaming = 0;
459 go7007_stream_stop(go);
460 mutex_lock(&go->hw_lock);
461 go7007_reset_encoder(go);
462 mutex_unlock(&go->hw_lock);
463 call_all(&go->v4l2_dev, video, s_stream, 0);
464
465 spin_lock_irqsave(&go->spinlock, flags);
466 INIT_LIST_HEAD(&go->vidq_active);
467 spin_unlock_irqrestore(&go->spinlock, flags);
468 v4l2_ctrl_grab(go->mpeg_video_gop_size, false);
469 v4l2_ctrl_grab(go->mpeg_video_gop_closure, false);
470 v4l2_ctrl_grab(go->mpeg_video_bitrate, false);
471 v4l2_ctrl_grab(go->mpeg_video_aspect_ratio, false);
472 /* Turn on Capture LED */
473 if (go->board_id == GO7007_BOARDID_ADS_USBAV_709)
474 go7007_write_addr(go, 0x3c82, 0x000d);
475 }
476
477 static struct vb2_ops go7007_video_qops = {
478 .queue_setup = go7007_queue_setup,
479 .buf_queue = go7007_buf_queue,
480 .buf_prepare = go7007_buf_prepare,
481 .buf_finish = go7007_buf_finish,
482 .start_streaming = go7007_start_streaming,
483 .stop_streaming = go7007_stop_streaming,
484 .wait_prepare = vb2_ops_wait_prepare,
485 .wait_finish = vb2_ops_wait_finish,
486 };
487
vidioc_g_parm(struct file * filp,void * priv,struct v4l2_streamparm * parm)488 static int vidioc_g_parm(struct file *filp, void *priv,
489 struct v4l2_streamparm *parm)
490 {
491 struct go7007 *go = video_drvdata(filp);
492 struct v4l2_fract timeperframe = {
493 .numerator = 1001 * go->fps_scale,
494 .denominator = go->sensor_framerate,
495 };
496
497 if (parm->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
498 return -EINVAL;
499
500 parm->parm.capture.readbuffers = 2;
501 parm->parm.capture.capability = V4L2_CAP_TIMEPERFRAME;
502 parm->parm.capture.timeperframe = timeperframe;
503
504 return 0;
505 }
506
vidioc_s_parm(struct file * filp,void * priv,struct v4l2_streamparm * parm)507 static int vidioc_s_parm(struct file *filp, void *priv,
508 struct v4l2_streamparm *parm)
509 {
510 struct go7007 *go = video_drvdata(filp);
511 unsigned int n, d;
512
513 if (parm->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
514 return -EINVAL;
515
516 n = go->sensor_framerate *
517 parm->parm.capture.timeperframe.numerator;
518 d = 1001 * parm->parm.capture.timeperframe.denominator;
519 if (n != 0 && d != 0 && n > d)
520 go->fps_scale = (n + d/2) / d;
521 else
522 go->fps_scale = 1;
523
524 return vidioc_g_parm(filp, priv, parm);
525 }
526
527 /* VIDIOC_ENUMSTD on go7007 were used for enumerating the supported fps and
528 its resolution, when the device is not connected to TV.
529 This is were an API abuse, probably used by the lack of specific IOCTL's to
530 enumerate it, by the time the driver was written.
531
532 However, since kernel 2.6.19, two new ioctls (VIDIOC_ENUM_FRAMEINTERVALS
533 and VIDIOC_ENUM_FRAMESIZES) were added for this purpose.
534
535 The two functions below implement the newer ioctls
536 */
vidioc_enum_framesizes(struct file * filp,void * priv,struct v4l2_frmsizeenum * fsize)537 static int vidioc_enum_framesizes(struct file *filp, void *priv,
538 struct v4l2_frmsizeenum *fsize)
539 {
540 struct go7007 *go = video_drvdata(filp);
541 int width, height;
542
543 if (fsize->index > 2)
544 return -EINVAL;
545
546 if (!valid_pixelformat(fsize->pixel_format))
547 return -EINVAL;
548
549 get_resolution(go, &width, &height);
550 fsize->type = V4L2_FRMSIZE_TYPE_DISCRETE;
551 fsize->discrete.width = (width >> fsize->index) & ~0xf;
552 fsize->discrete.height = (height >> fsize->index) & ~0xf;
553 return 0;
554 }
555
vidioc_enum_frameintervals(struct file * filp,void * priv,struct v4l2_frmivalenum * fival)556 static int vidioc_enum_frameintervals(struct file *filp, void *priv,
557 struct v4l2_frmivalenum *fival)
558 {
559 struct go7007 *go = video_drvdata(filp);
560 int width, height;
561 int i;
562
563 if (fival->index > 4)
564 return -EINVAL;
565
566 if (!valid_pixelformat(fival->pixel_format))
567 return -EINVAL;
568
569 if (!(go->board_info->sensor_flags & GO7007_SENSOR_SCALING)) {
570 get_resolution(go, &width, &height);
571 for (i = 0; i <= 2; i++)
572 if (fival->width == ((width >> i) & ~0xf) &&
573 fival->height == ((height >> i) & ~0xf))
574 break;
575 if (i > 2)
576 return -EINVAL;
577 }
578 fival->type = V4L2_FRMIVAL_TYPE_DISCRETE;
579 fival->discrete.numerator = 1001 * (fival->index + 1);
580 fival->discrete.denominator = go->sensor_framerate;
581 return 0;
582 }
583
vidioc_g_std(struct file * file,void * priv,v4l2_std_id * std)584 static int vidioc_g_std(struct file *file, void *priv, v4l2_std_id *std)
585 {
586 struct go7007 *go = video_drvdata(file);
587
588 *std = go->std;
589 return 0;
590 }
591
go7007_s_std(struct go7007 * go)592 static int go7007_s_std(struct go7007 *go)
593 {
594 if (go->std & V4L2_STD_625_50) {
595 go->standard = GO7007_STD_PAL;
596 go->sensor_framerate = 25025;
597 } else {
598 go->standard = GO7007_STD_NTSC;
599 go->sensor_framerate = 30000;
600 }
601
602 call_all(&go->v4l2_dev, video, s_std, go->std);
603 set_capture_size(go, NULL, 0);
604 return 0;
605 }
606
vidioc_s_std(struct file * file,void * priv,v4l2_std_id std)607 static int vidioc_s_std(struct file *file, void *priv, v4l2_std_id std)
608 {
609 struct go7007 *go = video_drvdata(file);
610
611 if (vb2_is_busy(&go->vidq))
612 return -EBUSY;
613
614 go->std = std;
615
616 return go7007_s_std(go);
617 }
618
vidioc_querystd(struct file * file,void * priv,v4l2_std_id * std)619 static int vidioc_querystd(struct file *file, void *priv, v4l2_std_id *std)
620 {
621 struct go7007 *go = video_drvdata(file);
622
623 return call_all(&go->v4l2_dev, video, querystd, std);
624 }
625
vidioc_enum_input(struct file * file,void * priv,struct v4l2_input * inp)626 static int vidioc_enum_input(struct file *file, void *priv,
627 struct v4l2_input *inp)
628 {
629 struct go7007 *go = video_drvdata(file);
630
631 if (inp->index >= go->board_info->num_inputs)
632 return -EINVAL;
633
634 strncpy(inp->name, go->board_info->inputs[inp->index].name,
635 sizeof(inp->name));
636
637 /* If this board has a tuner, it will be the first input */
638 if ((go->board_info->flags & GO7007_BOARD_HAS_TUNER) &&
639 inp->index == 0)
640 inp->type = V4L2_INPUT_TYPE_TUNER;
641 else
642 inp->type = V4L2_INPUT_TYPE_CAMERA;
643
644 if (go->board_info->num_aud_inputs)
645 inp->audioset = (1 << go->board_info->num_aud_inputs) - 1;
646 else
647 inp->audioset = 0;
648 inp->tuner = 0;
649 if (go->board_info->sensor_flags & GO7007_SENSOR_TV)
650 inp->std = video_devdata(file)->tvnorms;
651 else
652 inp->std = 0;
653
654 return 0;
655 }
656
657
vidioc_g_input(struct file * file,void * priv,unsigned int * input)658 static int vidioc_g_input(struct file *file, void *priv, unsigned int *input)
659 {
660 struct go7007 *go = video_drvdata(file);
661
662 *input = go->input;
663
664 return 0;
665 }
666
vidioc_enumaudio(struct file * file,void * fh,struct v4l2_audio * a)667 static int vidioc_enumaudio(struct file *file, void *fh, struct v4l2_audio *a)
668 {
669 struct go7007 *go = video_drvdata(file);
670
671 if (a->index >= go->board_info->num_aud_inputs)
672 return -EINVAL;
673 strlcpy(a->name, go->board_info->aud_inputs[a->index].name,
674 sizeof(a->name));
675 a->capability = V4L2_AUDCAP_STEREO;
676 return 0;
677 }
678
vidioc_g_audio(struct file * file,void * fh,struct v4l2_audio * a)679 static int vidioc_g_audio(struct file *file, void *fh, struct v4l2_audio *a)
680 {
681 struct go7007 *go = video_drvdata(file);
682
683 a->index = go->aud_input;
684 strlcpy(a->name, go->board_info->aud_inputs[go->aud_input].name,
685 sizeof(a->name));
686 a->capability = V4L2_AUDCAP_STEREO;
687 return 0;
688 }
689
vidioc_s_audio(struct file * file,void * fh,const struct v4l2_audio * a)690 static int vidioc_s_audio(struct file *file, void *fh,
691 const struct v4l2_audio *a)
692 {
693 struct go7007 *go = video_drvdata(file);
694
695 if (a->index >= go->board_info->num_aud_inputs)
696 return -EINVAL;
697 go->aud_input = a->index;
698 v4l2_subdev_call(go->sd_audio, audio, s_routing,
699 go->board_info->aud_inputs[go->aud_input].audio_input, 0, 0);
700 return 0;
701 }
702
go7007_s_input(struct go7007 * go)703 static void go7007_s_input(struct go7007 *go)
704 {
705 unsigned int input = go->input;
706
707 v4l2_subdev_call(go->sd_video, video, s_routing,
708 go->board_info->inputs[input].video_input, 0,
709 go->board_info->video_config);
710 if (go->board_info->num_aud_inputs) {
711 int aud_input = go->board_info->inputs[input].audio_index;
712
713 v4l2_subdev_call(go->sd_audio, audio, s_routing,
714 go->board_info->aud_inputs[aud_input].audio_input, 0, 0);
715 go->aud_input = aud_input;
716 }
717 }
718
vidioc_s_input(struct file * file,void * priv,unsigned int input)719 static int vidioc_s_input(struct file *file, void *priv, unsigned int input)
720 {
721 struct go7007 *go = video_drvdata(file);
722
723 if (input >= go->board_info->num_inputs)
724 return -EINVAL;
725 if (vb2_is_busy(&go->vidq))
726 return -EBUSY;
727
728 go->input = input;
729 go7007_s_input(go);
730
731 return 0;
732 }
733
vidioc_g_tuner(struct file * file,void * priv,struct v4l2_tuner * t)734 static int vidioc_g_tuner(struct file *file, void *priv,
735 struct v4l2_tuner *t)
736 {
737 struct go7007 *go = video_drvdata(file);
738
739 if (t->index != 0)
740 return -EINVAL;
741
742 strlcpy(t->name, "Tuner", sizeof(t->name));
743 return call_all(&go->v4l2_dev, tuner, g_tuner, t);
744 }
745
vidioc_s_tuner(struct file * file,void * priv,const struct v4l2_tuner * t)746 static int vidioc_s_tuner(struct file *file, void *priv,
747 const struct v4l2_tuner *t)
748 {
749 struct go7007 *go = video_drvdata(file);
750
751 if (t->index != 0)
752 return -EINVAL;
753
754 return call_all(&go->v4l2_dev, tuner, s_tuner, t);
755 }
756
vidioc_g_frequency(struct file * file,void * priv,struct v4l2_frequency * f)757 static int vidioc_g_frequency(struct file *file, void *priv,
758 struct v4l2_frequency *f)
759 {
760 struct go7007 *go = video_drvdata(file);
761
762 if (f->tuner)
763 return -EINVAL;
764
765 return call_all(&go->v4l2_dev, tuner, g_frequency, f);
766 }
767
vidioc_s_frequency(struct file * file,void * priv,const struct v4l2_frequency * f)768 static int vidioc_s_frequency(struct file *file, void *priv,
769 const struct v4l2_frequency *f)
770 {
771 struct go7007 *go = video_drvdata(file);
772
773 if (f->tuner)
774 return -EINVAL;
775
776 return call_all(&go->v4l2_dev, tuner, s_frequency, f);
777 }
778
vidioc_log_status(struct file * file,void * priv)779 static int vidioc_log_status(struct file *file, void *priv)
780 {
781 struct go7007 *go = video_drvdata(file);
782
783 v4l2_ctrl_log_status(file, priv);
784 return call_all(&go->v4l2_dev, core, log_status);
785 }
786
vidioc_subscribe_event(struct v4l2_fh * fh,const struct v4l2_event_subscription * sub)787 static int vidioc_subscribe_event(struct v4l2_fh *fh,
788 const struct v4l2_event_subscription *sub)
789 {
790
791 switch (sub->type) {
792 case V4L2_EVENT_CTRL:
793 return v4l2_ctrl_subscribe_event(fh, sub);
794 case V4L2_EVENT_MOTION_DET:
795 /* Allow for up to 30 events (1 second for NTSC) to be
796 * stored. */
797 return v4l2_event_subscribe(fh, sub, 30, NULL);
798 }
799 return -EINVAL;
800 }
801
802
go7007_s_ctrl(struct v4l2_ctrl * ctrl)803 static int go7007_s_ctrl(struct v4l2_ctrl *ctrl)
804 {
805 struct go7007 *go =
806 container_of(ctrl->handler, struct go7007, hdl);
807 unsigned y;
808 u8 *mt;
809
810 switch (ctrl->id) {
811 case V4L2_CID_PIXEL_THRESHOLD0:
812 go->modet[0].pixel_threshold = ctrl->val;
813 break;
814 case V4L2_CID_MOTION_THRESHOLD0:
815 go->modet[0].motion_threshold = ctrl->val;
816 break;
817 case V4L2_CID_MB_THRESHOLD0:
818 go->modet[0].mb_threshold = ctrl->val;
819 break;
820 case V4L2_CID_PIXEL_THRESHOLD1:
821 go->modet[1].pixel_threshold = ctrl->val;
822 break;
823 case V4L2_CID_MOTION_THRESHOLD1:
824 go->modet[1].motion_threshold = ctrl->val;
825 break;
826 case V4L2_CID_MB_THRESHOLD1:
827 go->modet[1].mb_threshold = ctrl->val;
828 break;
829 case V4L2_CID_PIXEL_THRESHOLD2:
830 go->modet[2].pixel_threshold = ctrl->val;
831 break;
832 case V4L2_CID_MOTION_THRESHOLD2:
833 go->modet[2].motion_threshold = ctrl->val;
834 break;
835 case V4L2_CID_MB_THRESHOLD2:
836 go->modet[2].mb_threshold = ctrl->val;
837 break;
838 case V4L2_CID_PIXEL_THRESHOLD3:
839 go->modet[3].pixel_threshold = ctrl->val;
840 break;
841 case V4L2_CID_MOTION_THRESHOLD3:
842 go->modet[3].motion_threshold = ctrl->val;
843 break;
844 case V4L2_CID_MB_THRESHOLD3:
845 go->modet[3].mb_threshold = ctrl->val;
846 break;
847 case V4L2_CID_DETECT_MD_REGION_GRID:
848 mt = go->modet_map;
849 for (y = 0; y < go->height / 16; y++, mt += go->width / 16)
850 memcpy(mt, ctrl->p_new.p_u8 + y * (720 / 16), go->width / 16);
851 break;
852 default:
853 return -EINVAL;
854 }
855 return 0;
856 }
857
858 static struct v4l2_file_operations go7007_fops = {
859 .owner = THIS_MODULE,
860 .open = v4l2_fh_open,
861 .release = vb2_fop_release,
862 .unlocked_ioctl = video_ioctl2,
863 .read = vb2_fop_read,
864 .mmap = vb2_fop_mmap,
865 .poll = vb2_fop_poll,
866 };
867
868 static const struct v4l2_ioctl_ops video_ioctl_ops = {
869 .vidioc_querycap = vidioc_querycap,
870 .vidioc_enum_fmt_vid_cap = vidioc_enum_fmt_vid_cap,
871 .vidioc_g_fmt_vid_cap = vidioc_g_fmt_vid_cap,
872 .vidioc_try_fmt_vid_cap = vidioc_try_fmt_vid_cap,
873 .vidioc_s_fmt_vid_cap = vidioc_s_fmt_vid_cap,
874 .vidioc_reqbufs = vb2_ioctl_reqbufs,
875 .vidioc_querybuf = vb2_ioctl_querybuf,
876 .vidioc_qbuf = vb2_ioctl_qbuf,
877 .vidioc_dqbuf = vb2_ioctl_dqbuf,
878 .vidioc_g_std = vidioc_g_std,
879 .vidioc_s_std = vidioc_s_std,
880 .vidioc_querystd = vidioc_querystd,
881 .vidioc_enum_input = vidioc_enum_input,
882 .vidioc_g_input = vidioc_g_input,
883 .vidioc_s_input = vidioc_s_input,
884 .vidioc_enumaudio = vidioc_enumaudio,
885 .vidioc_g_audio = vidioc_g_audio,
886 .vidioc_s_audio = vidioc_s_audio,
887 .vidioc_streamon = vb2_ioctl_streamon,
888 .vidioc_streamoff = vb2_ioctl_streamoff,
889 .vidioc_g_tuner = vidioc_g_tuner,
890 .vidioc_s_tuner = vidioc_s_tuner,
891 .vidioc_g_frequency = vidioc_g_frequency,
892 .vidioc_s_frequency = vidioc_s_frequency,
893 .vidioc_g_parm = vidioc_g_parm,
894 .vidioc_s_parm = vidioc_s_parm,
895 .vidioc_enum_framesizes = vidioc_enum_framesizes,
896 .vidioc_enum_frameintervals = vidioc_enum_frameintervals,
897 .vidioc_log_status = vidioc_log_status,
898 .vidioc_subscribe_event = vidioc_subscribe_event,
899 .vidioc_unsubscribe_event = v4l2_event_unsubscribe,
900 };
901
902 static struct video_device go7007_template = {
903 .name = "go7007",
904 .fops = &go7007_fops,
905 .release = video_device_release_empty,
906 .ioctl_ops = &video_ioctl_ops,
907 .tvnorms = V4L2_STD_ALL,
908 };
909
910 static const struct v4l2_ctrl_ops go7007_ctrl_ops = {
911 .s_ctrl = go7007_s_ctrl,
912 };
913
914 static const struct v4l2_ctrl_config go7007_pixel_threshold0_ctrl = {
915 .ops = &go7007_ctrl_ops,
916 .id = V4L2_CID_PIXEL_THRESHOLD0,
917 .name = "Pixel Threshold Region 0",
918 .type = V4L2_CTRL_TYPE_INTEGER,
919 .def = 20,
920 .max = 32767,
921 .step = 1,
922 };
923
924 static const struct v4l2_ctrl_config go7007_motion_threshold0_ctrl = {
925 .ops = &go7007_ctrl_ops,
926 .id = V4L2_CID_MOTION_THRESHOLD0,
927 .name = "Motion Threshold Region 0",
928 .type = V4L2_CTRL_TYPE_INTEGER,
929 .def = 80,
930 .max = 32767,
931 .step = 1,
932 };
933
934 static const struct v4l2_ctrl_config go7007_mb_threshold0_ctrl = {
935 .ops = &go7007_ctrl_ops,
936 .id = V4L2_CID_MB_THRESHOLD0,
937 .name = "MB Threshold Region 0",
938 .type = V4L2_CTRL_TYPE_INTEGER,
939 .def = 200,
940 .max = 32767,
941 .step = 1,
942 };
943
944 static const struct v4l2_ctrl_config go7007_pixel_threshold1_ctrl = {
945 .ops = &go7007_ctrl_ops,
946 .id = V4L2_CID_PIXEL_THRESHOLD1,
947 .name = "Pixel Threshold Region 1",
948 .type = V4L2_CTRL_TYPE_INTEGER,
949 .def = 20,
950 .max = 32767,
951 .step = 1,
952 };
953
954 static const struct v4l2_ctrl_config go7007_motion_threshold1_ctrl = {
955 .ops = &go7007_ctrl_ops,
956 .id = V4L2_CID_MOTION_THRESHOLD1,
957 .name = "Motion Threshold Region 1",
958 .type = V4L2_CTRL_TYPE_INTEGER,
959 .def = 80,
960 .max = 32767,
961 .step = 1,
962 };
963
964 static const struct v4l2_ctrl_config go7007_mb_threshold1_ctrl = {
965 .ops = &go7007_ctrl_ops,
966 .id = V4L2_CID_MB_THRESHOLD1,
967 .name = "MB Threshold Region 1",
968 .type = V4L2_CTRL_TYPE_INTEGER,
969 .def = 200,
970 .max = 32767,
971 .step = 1,
972 };
973
974 static const struct v4l2_ctrl_config go7007_pixel_threshold2_ctrl = {
975 .ops = &go7007_ctrl_ops,
976 .id = V4L2_CID_PIXEL_THRESHOLD2,
977 .name = "Pixel Threshold Region 2",
978 .type = V4L2_CTRL_TYPE_INTEGER,
979 .def = 20,
980 .max = 32767,
981 .step = 1,
982 };
983
984 static const struct v4l2_ctrl_config go7007_motion_threshold2_ctrl = {
985 .ops = &go7007_ctrl_ops,
986 .id = V4L2_CID_MOTION_THRESHOLD2,
987 .name = "Motion Threshold Region 2",
988 .type = V4L2_CTRL_TYPE_INTEGER,
989 .def = 80,
990 .max = 32767,
991 .step = 1,
992 };
993
994 static const struct v4l2_ctrl_config go7007_mb_threshold2_ctrl = {
995 .ops = &go7007_ctrl_ops,
996 .id = V4L2_CID_MB_THRESHOLD2,
997 .name = "MB Threshold Region 2",
998 .type = V4L2_CTRL_TYPE_INTEGER,
999 .def = 200,
1000 .max = 32767,
1001 .step = 1,
1002 };
1003
1004 static const struct v4l2_ctrl_config go7007_pixel_threshold3_ctrl = {
1005 .ops = &go7007_ctrl_ops,
1006 .id = V4L2_CID_PIXEL_THRESHOLD3,
1007 .name = "Pixel Threshold Region 3",
1008 .type = V4L2_CTRL_TYPE_INTEGER,
1009 .def = 20,
1010 .max = 32767,
1011 .step = 1,
1012 };
1013
1014 static const struct v4l2_ctrl_config go7007_motion_threshold3_ctrl = {
1015 .ops = &go7007_ctrl_ops,
1016 .id = V4L2_CID_MOTION_THRESHOLD3,
1017 .name = "Motion Threshold Region 3",
1018 .type = V4L2_CTRL_TYPE_INTEGER,
1019 .def = 80,
1020 .max = 32767,
1021 .step = 1,
1022 };
1023
1024 static const struct v4l2_ctrl_config go7007_mb_threshold3_ctrl = {
1025 .ops = &go7007_ctrl_ops,
1026 .id = V4L2_CID_MB_THRESHOLD3,
1027 .name = "MB Threshold Region 3",
1028 .type = V4L2_CTRL_TYPE_INTEGER,
1029 .def = 200,
1030 .max = 32767,
1031 .step = 1,
1032 };
1033
1034 static const struct v4l2_ctrl_config go7007_mb_regions_ctrl = {
1035 .ops = &go7007_ctrl_ops,
1036 .id = V4L2_CID_DETECT_MD_REGION_GRID,
1037 .dims = { 576 / 16, 720 / 16 },
1038 .max = 3,
1039 .step = 1,
1040 };
1041
go7007_v4l2_ctrl_init(struct go7007 * go)1042 int go7007_v4l2_ctrl_init(struct go7007 *go)
1043 {
1044 struct v4l2_ctrl_handler *hdl = &go->hdl;
1045 struct v4l2_ctrl *ctrl;
1046
1047 v4l2_ctrl_handler_init(hdl, 22);
1048 go->mpeg_video_gop_size = v4l2_ctrl_new_std(hdl, NULL,
1049 V4L2_CID_MPEG_VIDEO_GOP_SIZE, 0, 34, 1, 15);
1050 go->mpeg_video_gop_closure = v4l2_ctrl_new_std(hdl, NULL,
1051 V4L2_CID_MPEG_VIDEO_GOP_CLOSURE, 0, 1, 1, 1);
1052 go->mpeg_video_bitrate = v4l2_ctrl_new_std(hdl, NULL,
1053 V4L2_CID_MPEG_VIDEO_BITRATE,
1054 64000, 10000000, 1, 9800000);
1055 go->mpeg_video_b_frames = v4l2_ctrl_new_std(hdl, NULL,
1056 V4L2_CID_MPEG_VIDEO_B_FRAMES, 0, 2, 2, 0);
1057 go->mpeg_video_rep_seqheader = v4l2_ctrl_new_std(hdl, NULL,
1058 V4L2_CID_MPEG_VIDEO_REPEAT_SEQ_HEADER, 0, 1, 1, 1);
1059
1060 go->mpeg_video_aspect_ratio = v4l2_ctrl_new_std_menu(hdl, NULL,
1061 V4L2_CID_MPEG_VIDEO_ASPECT,
1062 V4L2_MPEG_VIDEO_ASPECT_16x9, 0,
1063 V4L2_MPEG_VIDEO_ASPECT_1x1);
1064 ctrl = v4l2_ctrl_new_std(hdl, NULL,
1065 V4L2_CID_JPEG_ACTIVE_MARKER, 0,
1066 V4L2_JPEG_ACTIVE_MARKER_DQT |
1067 V4L2_JPEG_ACTIVE_MARKER_DHT, 0,
1068 V4L2_JPEG_ACTIVE_MARKER_DQT |
1069 V4L2_JPEG_ACTIVE_MARKER_DHT);
1070 if (ctrl)
1071 ctrl->flags |= V4L2_CTRL_FLAG_READ_ONLY;
1072 v4l2_ctrl_new_custom(hdl, &go7007_pixel_threshold0_ctrl, NULL);
1073 v4l2_ctrl_new_custom(hdl, &go7007_motion_threshold0_ctrl, NULL);
1074 v4l2_ctrl_new_custom(hdl, &go7007_mb_threshold0_ctrl, NULL);
1075 v4l2_ctrl_new_custom(hdl, &go7007_pixel_threshold1_ctrl, NULL);
1076 v4l2_ctrl_new_custom(hdl, &go7007_motion_threshold1_ctrl, NULL);
1077 v4l2_ctrl_new_custom(hdl, &go7007_mb_threshold1_ctrl, NULL);
1078 v4l2_ctrl_new_custom(hdl, &go7007_pixel_threshold2_ctrl, NULL);
1079 v4l2_ctrl_new_custom(hdl, &go7007_motion_threshold2_ctrl, NULL);
1080 v4l2_ctrl_new_custom(hdl, &go7007_mb_threshold2_ctrl, NULL);
1081 v4l2_ctrl_new_custom(hdl, &go7007_pixel_threshold3_ctrl, NULL);
1082 v4l2_ctrl_new_custom(hdl, &go7007_motion_threshold3_ctrl, NULL);
1083 v4l2_ctrl_new_custom(hdl, &go7007_mb_threshold3_ctrl, NULL);
1084 v4l2_ctrl_new_custom(hdl, &go7007_mb_regions_ctrl, NULL);
1085 go->modet_mode = v4l2_ctrl_new_std_menu(hdl, NULL,
1086 V4L2_CID_DETECT_MD_MODE,
1087 V4L2_DETECT_MD_MODE_REGION_GRID,
1088 1 << V4L2_DETECT_MD_MODE_THRESHOLD_GRID,
1089 V4L2_DETECT_MD_MODE_DISABLED);
1090 if (hdl->error) {
1091 int rv = hdl->error;
1092
1093 v4l2_err(&go->v4l2_dev, "Could not register controls\n");
1094 return rv;
1095 }
1096 go->v4l2_dev.ctrl_handler = hdl;
1097 return 0;
1098 }
1099
go7007_v4l2_init(struct go7007 * go)1100 int go7007_v4l2_init(struct go7007 *go)
1101 {
1102 struct video_device *vdev = &go->vdev;
1103 int rv;
1104
1105 mutex_init(&go->serialize_lock);
1106 mutex_init(&go->queue_lock);
1107
1108 INIT_LIST_HEAD(&go->vidq_active);
1109 go->vidq.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
1110 go->vidq.io_modes = VB2_MMAP | VB2_USERPTR | VB2_READ;
1111 go->vidq.ops = &go7007_video_qops;
1112 go->vidq.mem_ops = &vb2_vmalloc_memops;
1113 go->vidq.drv_priv = go;
1114 go->vidq.buf_struct_size = sizeof(struct go7007_buffer);
1115 go->vidq.timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_MONOTONIC;
1116 go->vidq.lock = &go->queue_lock;
1117 rv = vb2_queue_init(&go->vidq);
1118 if (rv)
1119 return rv;
1120 *vdev = go7007_template;
1121 vdev->lock = &go->serialize_lock;
1122 vdev->queue = &go->vidq;
1123 video_set_drvdata(vdev, go);
1124 vdev->v4l2_dev = &go->v4l2_dev;
1125 if (!v4l2_device_has_op(&go->v4l2_dev, video, querystd))
1126 v4l2_disable_ioctl(vdev, VIDIOC_QUERYSTD);
1127 if (!(go->board_info->flags & GO7007_BOARD_HAS_TUNER)) {
1128 v4l2_disable_ioctl(vdev, VIDIOC_S_FREQUENCY);
1129 v4l2_disable_ioctl(vdev, VIDIOC_G_FREQUENCY);
1130 v4l2_disable_ioctl(vdev, VIDIOC_S_TUNER);
1131 v4l2_disable_ioctl(vdev, VIDIOC_G_TUNER);
1132 } else {
1133 struct v4l2_frequency f = {
1134 .type = V4L2_TUNER_ANALOG_TV,
1135 .frequency = 980,
1136 };
1137
1138 call_all(&go->v4l2_dev, tuner, s_frequency, &f);
1139 }
1140 if (!(go->board_info->sensor_flags & GO7007_SENSOR_TV)) {
1141 v4l2_disable_ioctl(vdev, VIDIOC_G_STD);
1142 v4l2_disable_ioctl(vdev, VIDIOC_S_STD);
1143 vdev->tvnorms = 0;
1144 }
1145 if (go->board_info->sensor_flags & GO7007_SENSOR_SCALING)
1146 v4l2_disable_ioctl(vdev, VIDIOC_ENUM_FRAMESIZES);
1147 if (go->board_info->num_aud_inputs == 0) {
1148 v4l2_disable_ioctl(vdev, VIDIOC_G_AUDIO);
1149 v4l2_disable_ioctl(vdev, VIDIOC_S_AUDIO);
1150 v4l2_disable_ioctl(vdev, VIDIOC_ENUMAUDIO);
1151 }
1152 /* Setup correct crystal frequency on this board */
1153 if (go->board_info->sensor_flags & GO7007_SENSOR_SAA7115)
1154 v4l2_subdev_call(go->sd_video, video, s_crystal_freq,
1155 SAA7115_FREQ_24_576_MHZ,
1156 SAA7115_FREQ_FL_APLL | SAA7115_FREQ_FL_UCGC |
1157 SAA7115_FREQ_FL_DOUBLE_ASCLK);
1158 go7007_s_input(go);
1159 if (go->board_info->sensor_flags & GO7007_SENSOR_TV)
1160 go7007_s_std(go);
1161 rv = video_register_device(vdev, VFL_TYPE_GRABBER, -1);
1162 if (rv < 0)
1163 return rv;
1164 dev_info(go->dev, "registered device %s [v4l2]\n",
1165 video_device_node_name(vdev));
1166
1167 return 0;
1168 }
1169
go7007_v4l2_remove(struct go7007 * go)1170 void go7007_v4l2_remove(struct go7007 *go)
1171 {
1172 v4l2_ctrl_handler_free(&go->hdl);
1173 }
1174