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