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