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