Staging: w35und: move supported band initialization out of wb35_probe()
[safe/jmp/linux-2.6] / drivers / staging / go7007 / go7007-v4l2.c
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>
29 #include <linux/videodev2.h>
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
41 static void deactivate_buffer(struct go7007_buffer *gobuf)
42 {
43         int i;
44
45         if (gobuf->state != BUF_STATE_IDLE) {
46                 list_del(&gobuf->stream);
47                 gobuf->state = BUF_STATE_IDLE;
48         }
49         if (gobuf->page_count > 0) {
50                 for (i = 0; i < gobuf->page_count; ++i)
51                         page_cache_release(gobuf->pages[i]);
52                 gobuf->page_count = 0;
53         }
54 }
55
56 static void abort_queued(struct go7007 *go)
57 {
58         struct go7007_buffer *gobuf, *next;
59
60         list_for_each_entry_safe(gobuf, next, &go->stream, stream) {
61                 deactivate_buffer(gobuf);
62         }
63 }
64
65 static int go7007_streamoff(struct go7007 *go)
66 {
67         int retval = -EINVAL;
68         unsigned long flags;
69
70         down(&go->hw_lock);
71         if (go->streaming) {
72                 go->streaming = 0;
73                 go7007_stream_stop(go);
74                 spin_lock_irqsave(&go->spinlock, flags);
75                 abort_queued(go);
76                 spin_unlock_irqrestore(&go->spinlock, flags);
77                 go7007_reset_encoder(go);
78                 retval = 0;
79         }
80         up(&go->hw_lock);
81         return 0;
82 }
83
84 static int go7007_open(struct file *file)
85 {
86         struct go7007 *go = video_get_drvdata(video_devdata(file));
87         struct go7007_file *gofh;
88
89         if (go->status != STATUS_ONLINE)
90                 return -EBUSY;
91         gofh = kmalloc(sizeof(struct go7007_file), GFP_KERNEL);
92         if (gofh == NULL)
93                 return -ENOMEM;
94         ++go->ref_count;
95         gofh->go = go;
96         init_MUTEX(&gofh->lock);
97         gofh->buf_count = 0;
98         file->private_data = gofh;
99         return 0;
100 }
101
102 static int go7007_release(struct file *file)
103 {
104         struct go7007_file *gofh = file->private_data;
105         struct go7007 *go = gofh->go;
106
107         if (gofh->buf_count > 0) {
108                 go7007_streamoff(go);
109                 go->in_use = 0;
110                 kfree(gofh->bufs);
111                 gofh->buf_count = 0;
112         }
113         kfree(gofh);
114         if (--go->ref_count == 0)
115                 kfree(go);
116         file->private_data = NULL;
117         return 0;
118 }
119
120 static u32 get_frame_type_flag(struct go7007_buffer *gobuf, int format)
121 {
122         u8 *f = page_address(gobuf->pages[0]);
123
124         switch (format) {
125         case GO7007_FORMAT_MJPEG:
126                 return V4L2_BUF_FLAG_KEYFRAME;
127         case GO7007_FORMAT_MPEG4:
128                 switch ((f[gobuf->frame_offset + 4] >> 6) & 0x3) {
129                 case 0:
130                         return V4L2_BUF_FLAG_KEYFRAME;
131                 case 1:
132                         return V4L2_BUF_FLAG_PFRAME;
133                 case 2:
134                         return V4L2_BUF_FLAG_BFRAME;
135                 default:
136                         return 0;
137                 }
138         case GO7007_FORMAT_MPEG1:
139         case GO7007_FORMAT_MPEG2:
140                 switch ((f[gobuf->frame_offset + 5] >> 3) & 0x7) {
141                 case 1:
142                         return V4L2_BUF_FLAG_KEYFRAME;
143                 case 2:
144                         return V4L2_BUF_FLAG_PFRAME;
145                 case 3:
146                         return V4L2_BUF_FLAG_BFRAME;
147                 default:
148                         return 0;
149                 }
150         }
151
152         return 0;
153 }
154
155 static int set_capture_size(struct go7007 *go, struct v4l2_format *fmt, int try)
156 {
157         int sensor_height = 0, sensor_width = 0;
158         int width, height, i;
159
160         if (fmt != NULL && fmt->fmt.pix.pixelformat != V4L2_PIX_FMT_MJPEG &&
161                         fmt->fmt.pix.pixelformat != V4L2_PIX_FMT_MPEG &&
162                         fmt->fmt.pix.pixelformat != V4L2_PIX_FMT_MPEG4)
163                 return -EINVAL;
164
165         switch (go->standard) {
166         case GO7007_STD_NTSC:
167                 sensor_width = 720;
168                 sensor_height = 480;
169                 break;
170         case GO7007_STD_PAL:
171                 sensor_width = 720;
172                 sensor_height = 576;
173                 break;
174         case GO7007_STD_OTHER:
175                 sensor_width = go->board_info->sensor_width;
176                 sensor_height = go->board_info->sensor_height;
177                 break;
178         }
179
180         if (fmt == NULL) {
181                 width = sensor_width;
182                 height = sensor_height;
183         } else if (go->board_info->sensor_flags & GO7007_SENSOR_SCALING) {
184                 if (fmt->fmt.pix.width > sensor_width)
185                         width = sensor_width;
186                 else if (fmt->fmt.pix.width < 144)
187                         width = 144;
188                 else
189                         width = fmt->fmt.pix.width & ~0x0f;
190
191                 if (fmt->fmt.pix.height > sensor_height)
192                         height = sensor_height;
193                 else if (fmt->fmt.pix.height < 96)
194                         height = 96;
195                 else
196                         height = fmt->fmt.pix.height & ~0x0f;
197         } else {
198                 int requested_size = fmt->fmt.pix.width * fmt->fmt.pix.height;
199                 int sensor_size = sensor_width * sensor_height;
200
201                 if (64 * requested_size < 9 * sensor_size) {
202                         width = sensor_width / 4;
203                         height = sensor_height / 4;
204                 } else if (64 * requested_size < 36 * sensor_size) {
205                         width = sensor_width / 2;
206                         height = sensor_height / 2;
207                 } else {
208                         width = sensor_width;
209                         height = sensor_height;
210                 }
211                 width &= ~0xf;
212                 height &= ~0xf;
213         }
214
215         if (fmt != NULL) {
216                 u32 pixelformat = fmt->fmt.pix.pixelformat;
217
218                 memset(fmt, 0, sizeof(*fmt));
219                 fmt->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
220                 fmt->fmt.pix.width = width;
221                 fmt->fmt.pix.height = height;
222                 fmt->fmt.pix.pixelformat = pixelformat;
223                 fmt->fmt.pix.field = V4L2_FIELD_NONE;
224                 fmt->fmt.pix.bytesperline = 0;
225                 fmt->fmt.pix.sizeimage = GO7007_BUF_SIZE;
226                 fmt->fmt.pix.colorspace = V4L2_COLORSPACE_SMPTE170M; /* ?? */
227         }
228
229         if (try)
230                 return 0;
231
232         go->width = width;
233         go->height = height;
234         go->encoder_h_offset = go->board_info->sensor_h_offset;
235         go->encoder_v_offset = go->board_info->sensor_v_offset;
236         for (i = 0; i < 4; ++i)
237                 go->modet[i].enable = 0;
238         for (i = 0; i < 1624; ++i)
239                 go->modet_map[i] = 0;
240
241         if (go->board_info->sensor_flags & GO7007_SENSOR_SCALING) {
242                 struct video_decoder_resolution res;
243
244                 res.width = width;
245                 if (height > sensor_height / 2) {
246                         res.height = height / 2;
247                         go->encoder_v_halve = 0;
248                 } else {
249                         res.height = height;
250                         go->encoder_v_halve = 1;
251                 }
252                 if (go->i2c_adapter_online)
253                         i2c_clients_command(&go->i2c_adapter,
254                                         DECODER_SET_RESOLUTION, &res);
255         } else {
256                 if (width <= sensor_width / 4) {
257                         go->encoder_h_halve = 1;
258                         go->encoder_v_halve = 1;
259                         go->encoder_subsample = 1;
260                 } else if (width <= sensor_width / 2) {
261                         go->encoder_h_halve = 1;
262                         go->encoder_v_halve = 1;
263                         go->encoder_subsample = 0;
264                 } else {
265                         go->encoder_h_halve = 0;
266                         go->encoder_v_halve = 0;
267                         go->encoder_subsample = 0;
268                 }
269         }
270
271         if (fmt == NULL)
272                 return 0;
273
274         switch (fmt->fmt.pix.pixelformat) {
275         case V4L2_PIX_FMT_MPEG:
276                 if (go->format == GO7007_FORMAT_MPEG1 ||
277                                 go->format == GO7007_FORMAT_MPEG2 ||
278                                 go->format == GO7007_FORMAT_MPEG4)
279                         break;
280                 go->format = GO7007_FORMAT_MPEG1;
281                 go->pali = 0;
282                 go->aspect_ratio = GO7007_RATIO_1_1;
283                 go->gop_size = go->sensor_framerate / 1000;
284                 go->ipb = 0;
285                 go->closed_gop = 1;
286                 go->repeat_seqhead = 1;
287                 go->seq_header_enable = 1;
288                 go->gop_header_enable = 1;
289                 go->dvd_mode = 0;
290                 break;
291         /* Backwards compatibility only! */
292         case V4L2_PIX_FMT_MPEG4:
293                 if (go->format == GO7007_FORMAT_MPEG4)
294                         break;
295                 go->format = GO7007_FORMAT_MPEG4;
296                 go->pali = 0xf5;
297                 go->aspect_ratio = GO7007_RATIO_1_1;
298                 go->gop_size = go->sensor_framerate / 1000;
299                 go->ipb = 0;
300                 go->closed_gop = 1;
301                 go->repeat_seqhead = 1;
302                 go->seq_header_enable = 1;
303                 go->gop_header_enable = 1;
304                 go->dvd_mode = 0;
305                 break;
306         case V4L2_PIX_FMT_MJPEG:
307                 go->format = GO7007_FORMAT_MJPEG;
308                 go->pali = 0;
309                 go->aspect_ratio = GO7007_RATIO_1_1;
310                 go->gop_size = 0;
311                 go->ipb = 0;
312                 go->closed_gop = 0;
313                 go->repeat_seqhead = 0;
314                 go->seq_header_enable = 0;
315                 go->gop_header_enable = 0;
316                 go->dvd_mode = 0;
317                 break;
318         }
319         return 0;
320 }
321
322 static int clip_to_modet_map(struct go7007 *go, int region,
323                 struct v4l2_clip *clip_list)
324 {
325         struct v4l2_clip clip, *clip_ptr;
326         int x, y, mbnum;
327
328         /* Check if coordinates are OK and if any macroblocks are already
329          * used by other regions (besides 0) */
330         clip_ptr = clip_list;
331         while (clip_ptr) {
332                 if (copy_from_user(&clip, clip_ptr, sizeof(clip)))
333                         return -EFAULT;
334                 if (clip.c.left < 0 || (clip.c.left & 0xF) ||
335                                 clip.c.width <= 0 || (clip.c.width & 0xF))
336                         return -EINVAL;
337                 if (clip.c.left + clip.c.width > go->width)
338                         return -EINVAL;
339                 if (clip.c.top < 0 || (clip.c.top & 0xF) ||
340                                 clip.c.height <= 0 || (clip.c.height & 0xF))
341                         return -EINVAL;
342                 if (clip.c.top + clip.c.height > go->height)
343                         return -EINVAL;
344                 for (y = 0; y < clip.c.height; y += 16)
345                         for (x = 0; x < clip.c.width; x += 16) {
346                                 mbnum = (go->width >> 4) *
347                                                 ((clip.c.top + y) >> 4) +
348                                         ((clip.c.left + x) >> 4);
349                                 if (go->modet_map[mbnum] != 0 &&
350                                                 go->modet_map[mbnum] != region)
351                                         return -EBUSY;
352                         }
353                 clip_ptr = clip.next;
354         }
355
356         /* Clear old region macroblocks */
357         for (mbnum = 0; mbnum < 1624; ++mbnum)
358                 if (go->modet_map[mbnum] == region)
359                         go->modet_map[mbnum] = 0;
360
361         /* Claim macroblocks in this list */
362         clip_ptr = clip_list;
363         while (clip_ptr) {
364                 if (copy_from_user(&clip, clip_ptr, sizeof(clip)))
365                         return -EFAULT;
366                 for (y = 0; y < clip.c.height; y += 16)
367                         for (x = 0; x < clip.c.width; x += 16) {
368                                 mbnum = (go->width >> 4) *
369                                                 ((clip.c.top + y) >> 4) +
370                                         ((clip.c.left + x) >> 4);
371                                 go->modet_map[mbnum] = region;
372                         }
373                 clip_ptr = clip.next;
374         }
375         return 0;
376 }
377
378 static long go7007_do_ioctl(struct file *file, unsigned int cmd, void *arg)
379 {
380         struct go7007_file *gofh = file->private_data;
381         struct go7007 *go = gofh->go;
382         unsigned long flags;
383         int retval = 0;
384
385         switch (cmd) {
386         case VIDIOC_QUERYCAP:
387         {
388                 struct v4l2_capability *cap = arg;
389
390                 memset(cap, 0, sizeof(*cap));
391                 strcpy(cap->driver, "go7007");
392                 strncpy(cap->card, go->name, sizeof(cap->card));
393                 cap->version = KERNEL_VERSION(0, 9, 8);
394                 cap->capabilities = V4L2_CAP_VIDEO_CAPTURE |
395                                 V4L2_CAP_STREAMING; /* | V4L2_CAP_AUDIO; */
396                 if (go->board_info->flags & GO7007_BOARD_HAS_TUNER)
397                         cap->capabilities |= V4L2_CAP_TUNER;
398                 return 0;
399         }
400         case VIDIOC_ENUM_FMT:
401         {
402                 struct v4l2_fmtdesc *fmt = arg;
403                 unsigned int index;
404                 char *desc;
405                 u32 pixelformat;
406
407                 if (fmt->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
408                         return -EINVAL;
409                 switch (fmt->index) {
410                 case 0:
411                         pixelformat = V4L2_PIX_FMT_MJPEG;
412                         desc = "Motion-JPEG";
413                         break;
414                 case 1:
415                         pixelformat = V4L2_PIX_FMT_MPEG;
416                         desc = "MPEG1/MPEG2/MPEG4";
417                         break;
418                 default:
419                         return -EINVAL;
420                 }
421                 index = fmt->index;
422                 memset(fmt, 0, sizeof(*fmt));
423                 fmt->index = index;
424                 fmt->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
425                 fmt->flags = V4L2_FMT_FLAG_COMPRESSED;
426                 strncpy(fmt->description, desc, sizeof(fmt->description));
427                 fmt->pixelformat = pixelformat;
428
429                 return 0;
430         }
431         case VIDIOC_TRY_FMT:
432         {
433                 struct v4l2_format *fmt = arg;
434
435                 if (fmt->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
436                         return -EINVAL;
437                 return set_capture_size(go, fmt, 1);
438         }
439         case VIDIOC_G_FMT:
440         {
441                 struct v4l2_format *fmt = arg;
442
443                 if (fmt->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
444                         return -EINVAL;
445                 memset(fmt, 0, sizeof(*fmt));
446                 fmt->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
447                 fmt->fmt.pix.width = go->width;
448                 fmt->fmt.pix.height = go->height;
449                 fmt->fmt.pix.pixelformat = go->format == GO7007_FORMAT_MJPEG ?
450                         V4L2_PIX_FMT_MJPEG : V4L2_PIX_FMT_MPEG;
451                 fmt->fmt.pix.field = V4L2_FIELD_NONE;
452                 fmt->fmt.pix.bytesperline = 0;
453                 fmt->fmt.pix.sizeimage = GO7007_BUF_SIZE;
454                 fmt->fmt.pix.colorspace = V4L2_COLORSPACE_SMPTE170M; /* ?? */
455                 return 0;
456         }
457         case VIDIOC_S_FMT:
458         {
459                 struct v4l2_format *fmt = arg;
460
461                 if (fmt->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
462                         return -EINVAL;
463                 if (go->streaming)
464                         return -EBUSY;
465                 return set_capture_size(go, fmt, 0);
466         }
467         case VIDIOC_G_FBUF:
468         case VIDIOC_S_FBUF:
469                 return -EINVAL;
470         case VIDIOC_REQBUFS:
471         {
472                 struct v4l2_requestbuffers *req = arg;
473                 unsigned int count, i;
474
475                 if (go->streaming)
476                         return -EBUSY;
477                 if (req->type != V4L2_BUF_TYPE_VIDEO_CAPTURE ||
478                                 req->memory != V4L2_MEMORY_MMAP)
479                         return -EINVAL;
480
481                 down(&gofh->lock);
482                 retval = -EBUSY;
483                 for (i = 0; i < gofh->buf_count; ++i)
484                         if (gofh->bufs[i].mapped > 0)
485                                 goto unlock_and_return;
486                 down(&go->hw_lock);
487                 if (go->in_use > 0 && gofh->buf_count == 0) {
488                         up(&go->hw_lock);
489                         goto unlock_and_return;
490                 }
491                 if (gofh->buf_count > 0)
492                         kfree(gofh->bufs);
493                 retval = -ENOMEM;
494                 count = req->count;
495                 if (count > 0) {
496                         if (count < 2)
497                                 count = 2;
498                         if (count > 32)
499                                 count = 32;
500                         gofh->bufs = kmalloc(count *
501                                                 sizeof(struct go7007_buffer),
502                                         GFP_KERNEL);
503                         if (gofh->bufs == NULL) {
504                                 up(&go->hw_lock);
505                                 goto unlock_and_return;
506                         }
507                         memset(gofh->bufs, 0,
508                                         count * sizeof(struct go7007_buffer));
509                         for (i = 0; i < count; ++i) {
510                                 gofh->bufs[i].go = go;
511                                 gofh->bufs[i].index = i;
512                                 gofh->bufs[i].state = BUF_STATE_IDLE;
513                                 gofh->bufs[i].mapped = 0;
514                         }
515                         go->in_use = 1;
516                 } else {
517                         go->in_use = 0;
518                 }
519                 gofh->buf_count = count;
520                 up(&go->hw_lock);
521                 up(&gofh->lock);
522                 memset(req, 0, sizeof(*req));
523                 req->count = count;
524                 req->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
525                 req->memory = V4L2_MEMORY_MMAP;
526                 return 0;
527         }
528         case VIDIOC_QUERYBUF:
529         {
530                 struct v4l2_buffer *buf = arg;
531                 unsigned int index;
532
533                 retval = -EINVAL;
534                 if (buf->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
535                         return -EINVAL;
536                 index = buf->index;
537                 down(&gofh->lock);
538                 if (index >= gofh->buf_count)
539                         goto unlock_and_return;
540                 memset(buf, 0, sizeof(*buf));
541                 buf->index = index;
542                 buf->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
543                 switch (gofh->bufs[index].state) {
544                 case BUF_STATE_QUEUED:
545                         buf->flags = V4L2_BUF_FLAG_QUEUED;
546                         break;
547                 case BUF_STATE_DONE:
548                         buf->flags = V4L2_BUF_FLAG_DONE;
549                         break;
550                 default:
551                         buf->flags = 0;
552                 }
553                 if (gofh->bufs[index].mapped)
554                         buf->flags |= V4L2_BUF_FLAG_MAPPED;
555                 buf->memory = V4L2_MEMORY_MMAP;
556                 buf->m.offset = index * GO7007_BUF_SIZE;
557                 buf->length = GO7007_BUF_SIZE;
558                 up(&gofh->lock);
559
560                 return 0;
561         }
562         case VIDIOC_QBUF:
563         {
564                 struct v4l2_buffer *buf = arg;
565                 struct go7007_buffer *gobuf;
566                 int ret;
567
568                 retval = -EINVAL;
569                 if (buf->type != V4L2_BUF_TYPE_VIDEO_CAPTURE ||
570                                 buf->memory != V4L2_MEMORY_MMAP)
571                         return -EINVAL;
572                 down(&gofh->lock);
573                 if (buf->index < 0 || buf->index >= gofh->buf_count)
574                         goto unlock_and_return;
575                 gobuf = &gofh->bufs[buf->index];
576                 if (gobuf->mapped == 0)
577                         goto unlock_and_return;
578                 retval = -EBUSY;
579                 if (gobuf->state != BUF_STATE_IDLE)
580                         goto unlock_and_return;
581                 /* offset will be 0 until we really support USERPTR streaming */
582                 gobuf->offset = gobuf->user_addr & ~PAGE_MASK;
583                 gobuf->bytesused = 0;
584                 gobuf->frame_offset = 0;
585                 gobuf->modet_active = 0;
586                 if (gobuf->offset > 0)
587                         gobuf->page_count = GO7007_BUF_PAGES + 1;
588                 else
589                         gobuf->page_count = GO7007_BUF_PAGES;
590                 retval = -ENOMEM;
591                 down_read(&current->mm->mmap_sem);
592                 ret = get_user_pages(current, current->mm,
593                                 gobuf->user_addr & PAGE_MASK, gobuf->page_count,
594                                 1, 1, gobuf->pages, NULL);
595                 up_read(&current->mm->mmap_sem);
596                 if (ret != gobuf->page_count) {
597                         int i;
598                         for (i = 0; i < ret; ++i)
599                                 page_cache_release(gobuf->pages[i]);
600                         gobuf->page_count = 0;
601                         goto unlock_and_return;
602                 }
603                 gobuf->state = BUF_STATE_QUEUED;
604                 spin_lock_irqsave(&go->spinlock, flags);
605                 list_add_tail(&gobuf->stream, &go->stream);
606                 spin_unlock_irqrestore(&go->spinlock, flags);
607                 up(&gofh->lock);
608                 return 0;
609         }
610         case VIDIOC_DQBUF:
611         {
612                 struct v4l2_buffer *buf = arg;
613                 struct go7007_buffer *gobuf;
614                 u32 frame_type_flag;
615                 DEFINE_WAIT(wait);
616
617                 if (buf->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
618                         return -EINVAL;
619                 if (buf->memory != V4L2_MEMORY_MMAP)
620                         return -EINVAL;
621                 down(&gofh->lock);
622                 retval = -EINVAL;
623                 if (list_empty(&go->stream))
624                         goto unlock_and_return;
625                 gobuf = list_entry(go->stream.next,
626                                 struct go7007_buffer, stream);
627                 retval = -EAGAIN;
628                 if (gobuf->state != BUF_STATE_DONE &&
629                                 !(file->f_flags & O_NONBLOCK)) {
630                         for (;;) {
631                                 prepare_to_wait(&go->frame_waitq, &wait,
632                                                 TASK_INTERRUPTIBLE);
633                                 if (gobuf->state == BUF_STATE_DONE)
634                                         break;
635                                 if (signal_pending(current)) {
636                                         retval = -ERESTARTSYS;
637                                         break;
638                                 }
639                                 schedule();
640                         }
641                         finish_wait(&go->frame_waitq, &wait);
642                 }
643                 if (gobuf->state != BUF_STATE_DONE)
644                         goto unlock_and_return;
645                 spin_lock_irqsave(&go->spinlock, flags);
646                 deactivate_buffer(gobuf);
647                 spin_unlock_irqrestore(&go->spinlock, flags);
648                 frame_type_flag = get_frame_type_flag(gobuf, go->format);
649                 gobuf->state = BUF_STATE_IDLE;
650                 memset(buf, 0, sizeof(*buf));
651                 buf->index = gobuf->index;
652                 buf->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
653                 buf->bytesused = gobuf->bytesused;
654                 buf->flags = V4L2_BUF_FLAG_MAPPED | frame_type_flag;
655                 buf->field = V4L2_FIELD_NONE;
656                 buf->timestamp = gobuf->timestamp;
657                 buf->sequence = gobuf->seq;
658                 buf->memory = V4L2_MEMORY_MMAP;
659                 buf->m.offset = gobuf->index * GO7007_BUF_SIZE;
660                 buf->length = GO7007_BUF_SIZE;
661                 buf->reserved = gobuf->modet_active;
662                 up(&gofh->lock);
663                 return 0;
664         }
665         case VIDIOC_STREAMON:
666         {
667                 unsigned int *type = arg;
668
669                 if (*type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
670                         return -EINVAL;
671                 down(&gofh->lock);
672                 down(&go->hw_lock);
673                 if (!go->streaming) {
674                         go->streaming = 1;
675                         go->next_seq = 0;
676                         go->active_buf = NULL;
677                         if (go7007_start_encoder(go) < 0)
678                                 retval = -EIO;
679                         else
680                                 retval = 0;
681                 }
682                 up(&go->hw_lock);
683                 up(&gofh->lock);
684                 return retval;
685         }
686         case VIDIOC_STREAMOFF:
687         {
688                 unsigned int *type = arg;
689
690                 if (*type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
691                         return -EINVAL;
692                 down(&gofh->lock);
693                 go7007_streamoff(go);
694                 up(&gofh->lock);
695                 return 0;
696         }
697         case VIDIOC_QUERYCTRL:
698         {
699                 struct v4l2_queryctrl *ctrl = arg;
700                 u32 id;
701
702                 if (!go->i2c_adapter_online)
703                         return -EIO;
704                 id = ctrl->id;
705                 memset(ctrl, 0, sizeof(*ctrl));
706                 ctrl->id = id;
707                 i2c_clients_command(&go->i2c_adapter, VIDIOC_QUERYCTRL, arg);
708                 return ctrl->name[0] == 0 ? -EINVAL : 0;
709         }
710         case VIDIOC_G_CTRL:
711         {
712                 struct v4l2_control *ctrl = arg;
713                 struct v4l2_queryctrl query;
714
715                 if (!go->i2c_adapter_online)
716                         return -EIO;
717                 memset(&query, 0, sizeof(query));
718                 query.id = ctrl->id;
719                 i2c_clients_command(&go->i2c_adapter, VIDIOC_QUERYCTRL, &query);
720                 if (query.name[0] == 0)
721                         return -EINVAL;
722                 i2c_clients_command(&go->i2c_adapter, VIDIOC_G_CTRL, arg);
723                 return 0;
724         }
725         case VIDIOC_S_CTRL:
726         {
727                 struct v4l2_control *ctrl = arg;
728                 struct v4l2_queryctrl query;
729
730                 if (!go->i2c_adapter_online)
731                         return -EIO;
732                 memset(&query, 0, sizeof(query));
733                 query.id = ctrl->id;
734                 i2c_clients_command(&go->i2c_adapter, VIDIOC_QUERYCTRL, &query);
735                 if (query.name[0] == 0)
736                         return -EINVAL;
737                 i2c_clients_command(&go->i2c_adapter, VIDIOC_S_CTRL, arg);
738                 return 0;
739         }
740         case VIDIOC_G_PARM:
741         {
742                 struct v4l2_streamparm *parm = arg;
743                 struct v4l2_fract timeperframe = {
744                         .numerator = 1001 *  go->fps_scale,
745                         .denominator = go->sensor_framerate,
746                 };
747
748                 if (parm->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
749                         return -EINVAL;
750                 memset(parm, 0, sizeof(*parm));
751                 parm->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
752                 parm->parm.capture.capability |= V4L2_CAP_TIMEPERFRAME;
753                 parm->parm.capture.timeperframe = timeperframe;
754                 return 0;
755         }
756         case VIDIOC_S_PARM:
757         {
758                 struct v4l2_streamparm *parm = arg;
759                 unsigned int n, d;
760
761                 if (parm->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
762                         return -EINVAL;
763                 if (parm->parm.capture.capturemode != 0)
764                         return -EINVAL;
765                 n = go->sensor_framerate *
766                         parm->parm.capture.timeperframe.numerator;
767                 d = 1001 * parm->parm.capture.timeperframe.denominator;
768                 if (n != 0 && d != 0 && n > d)
769                         go->fps_scale = (n + d/2) / d;
770                 else
771                         go->fps_scale = 1;
772                 return 0;
773         }
774         case VIDIOC_ENUMSTD:
775         {
776                 struct v4l2_standard *std = arg;
777
778                 if ((go->board_info->flags & GO7007_BOARD_HAS_TUNER) &&
779                                 go->input == go->board_info->num_inputs - 1) {
780                         if (!go->i2c_adapter_online)
781                                 return -EIO;
782                         i2c_clients_command(&go->i2c_adapter,
783                                                 VIDIOC_ENUMSTD, arg);
784                         if (!std->id) /* hack to indicate EINVAL from tuner */
785                                 return -EINVAL;
786                 } else if (go->board_info->sensor_flags & GO7007_SENSOR_TV) {
787                         switch (std->index) {
788                         case 0:
789                                 v4l2_video_std_construct(std,
790                                                 V4L2_STD_NTSC, "NTSC");
791                                 break;
792                         case 1:
793                                 v4l2_video_std_construct(std,
794                                                 V4L2_STD_PAL | V4L2_STD_SECAM,
795                                                 "PAL/SECAM");
796                                 break;
797                         default:
798                                 return -EINVAL;
799                         }
800                 } else {
801                         if (std->index != 0)
802                                 return -EINVAL;
803                         memset(std, 0, sizeof(*std));
804                         snprintf(std->name, sizeof(std->name), "%dx%d, %dfps",
805                                 go->board_info->sensor_width,
806                                 go->board_info->sensor_height,
807                                 go->board_info->sensor_framerate / 1000);
808                         std->frameperiod.numerator = 1001;
809                         std->frameperiod.denominator =
810                                         go->board_info->sensor_framerate;
811                 }
812                 return 0;
813         }
814         case VIDIOC_G_STD:
815         {
816                 v4l2_std_id *std = arg;
817
818                 if ((go->board_info->flags & GO7007_BOARD_HAS_TUNER) &&
819                                 go->input == go->board_info->num_inputs - 1) {
820                         if (!go->i2c_adapter_online)
821                                 return -EIO;
822                         i2c_clients_command(&go->i2c_adapter,
823                                                 VIDIOC_G_STD, arg);
824                 } else if (go->board_info->sensor_flags & GO7007_SENSOR_TV) {
825                         if (go->standard == GO7007_STD_NTSC)
826                                 *std = V4L2_STD_NTSC;
827                         else
828                                 *std = V4L2_STD_PAL | V4L2_STD_SECAM;
829                 } else
830                         *std = 0;
831                 return 0;
832         }
833         case VIDIOC_S_STD:
834         {
835                 v4l2_std_id *std = arg;
836
837                 if (go->streaming)
838                         return -EBUSY;
839                 if (!(go->board_info->sensor_flags & GO7007_SENSOR_TV) &&
840                                 *std != 0)
841                         return -EINVAL;
842                 if (*std == 0)
843                         return -EINVAL;
844                 if ((go->board_info->flags & GO7007_BOARD_HAS_TUNER) &&
845                                 go->input == go->board_info->num_inputs - 1) {
846                         if (!go->i2c_adapter_online)
847                                 return -EIO;
848                         i2c_clients_command(&go->i2c_adapter,
849                                                 VIDIOC_S_STD, arg);
850                         if (!*std) /* hack to indicate EINVAL from tuner */
851                                 return -EINVAL;
852                 }
853                 if (*std & V4L2_STD_NTSC) {
854                         go->standard = GO7007_STD_NTSC;
855                         go->sensor_framerate = 30000;
856                 } else if (*std & V4L2_STD_PAL) {
857                         go->standard = GO7007_STD_PAL;
858                         go->sensor_framerate = 25025;
859                 } else if (*std & V4L2_STD_SECAM) {
860                         go->standard = GO7007_STD_PAL;
861                         go->sensor_framerate = 25025;
862                 } else
863                         return -EINVAL;
864                 if (go->i2c_adapter_online)
865                         i2c_clients_command(&go->i2c_adapter,
866                                             VIDIOC_S_STD, std);
867                 set_capture_size(go, NULL, 0);
868                 return 0;
869         }
870         case VIDIOC_QUERYSTD:
871         {
872                 v4l2_std_id *std = arg;
873
874                 if ((go->board_info->flags & GO7007_BOARD_HAS_TUNER) &&
875                                 go->input == go->board_info->num_inputs - 1) {
876                         if (!go->i2c_adapter_online)
877                                 return -EIO;
878                         i2c_clients_command(&go->i2c_adapter,
879                                                 VIDIOC_QUERYSTD, arg);
880                 } else if (go->board_info->sensor_flags & GO7007_SENSOR_TV)
881                         *std = V4L2_STD_NTSC | V4L2_STD_PAL | V4L2_STD_SECAM;
882                 else
883                         *std = 0;
884                 return 0;
885         }
886         case VIDIOC_ENUMINPUT:
887         {
888                 struct v4l2_input *inp = arg;
889                 int index;
890
891                 if (inp->index >= go->board_info->num_inputs)
892                         return -EINVAL;
893                 index = inp->index;
894                 memset(inp, 0, sizeof(*inp));
895                 inp->index = index;
896                 strncpy(inp->name, go->board_info->inputs[index].name,
897                                 sizeof(inp->name));
898                 /* If this board has a tuner, it will be the last input */
899                 if ((go->board_info->flags & GO7007_BOARD_HAS_TUNER) &&
900                                 index == go->board_info->num_inputs - 1)
901                         inp->type = V4L2_INPUT_TYPE_TUNER;
902                 else
903                         inp->type = V4L2_INPUT_TYPE_CAMERA;
904                 inp->audioset = 0;
905                 inp->tuner = 0;
906                 if (go->board_info->sensor_flags & GO7007_SENSOR_TV)
907                         inp->std = V4L2_STD_NTSC | V4L2_STD_PAL |
908                                                         V4L2_STD_SECAM;
909                 else
910                         inp->std = 0;
911                 return 0;
912         }
913         case VIDIOC_G_INPUT:
914         {
915                 int *input = arg;
916
917                 *input = go->input;
918                 return 0;
919         }
920         case VIDIOC_S_INPUT:
921         {
922                 int *input = arg;
923
924                 if (*input >= go->board_info->num_inputs)
925                         return -EINVAL;
926                 if (go->streaming)
927                         return -EBUSY;
928                 go->input = *input;
929                 if (go->i2c_adapter_online) {
930                         i2c_clients_command(&go->i2c_adapter, VIDIOC_S_INPUT,
931                                 &go->board_info->inputs[*input].video_input);
932                         i2c_clients_command(&go->i2c_adapter, VIDIOC_S_AUDIO,
933                                 &go->board_info->inputs[*input].audio_input);
934                 }
935                 return 0;
936         }
937         case VIDIOC_G_TUNER:
938         {
939                 struct v4l2_tuner *t = arg;
940
941                 if (!(go->board_info->flags & GO7007_BOARD_HAS_TUNER))
942                         return -EINVAL;
943                 if (t->index != 0)
944                         return -EINVAL;
945                 if (!go->i2c_adapter_online)
946                         return -EIO;
947                 i2c_clients_command(&go->i2c_adapter, VIDIOC_G_TUNER, arg);
948                 t->index = 0;
949                 return 0;
950         }
951         case VIDIOC_S_TUNER:
952         {
953                 struct v4l2_tuner *t = arg;
954
955                 if (!(go->board_info->flags & GO7007_BOARD_HAS_TUNER))
956                         return -EINVAL;
957                 if (t->index != 0)
958                         return -EINVAL;
959                 if (!go->i2c_adapter_online)
960                         return -EIO;
961                 switch (go->board_id) {
962                 case GO7007_BOARDID_PX_TV402U_NA:
963                 case GO7007_BOARDID_PX_TV402U_JP:
964                         /* No selectable options currently */
965                         if (t->audmode != V4L2_TUNER_MODE_STEREO)
966                                 return -EINVAL;
967                         break;
968                 }
969                 i2c_clients_command(&go->i2c_adapter, VIDIOC_S_TUNER, arg);
970                 return 0;
971         }
972         case VIDIOC_G_FREQUENCY:
973         {
974                 struct v4l2_frequency *f = arg;
975
976                 if (!(go->board_info->flags & GO7007_BOARD_HAS_TUNER))
977                         return -EINVAL;
978                 if (!go->i2c_adapter_online)
979                         return -EIO;
980                 memset(f, 0, sizeof(*f));
981                 f->type = V4L2_TUNER_ANALOG_TV;
982                 i2c_clients_command(&go->i2c_adapter, VIDIOC_G_FREQUENCY, arg);
983                 return 0;
984         }
985         case VIDIOC_S_FREQUENCY:
986         {
987                 if (!(go->board_info->flags & GO7007_BOARD_HAS_TUNER))
988                         return -EINVAL;
989                 if (!go->i2c_adapter_online)
990                         return -EIO;
991                 i2c_clients_command(&go->i2c_adapter, VIDIOC_S_FREQUENCY, arg);
992                 return 0;
993         }
994         case VIDIOC_CROPCAP:
995         {
996                 struct v4l2_cropcap *cropcap = arg;
997
998                 if (cropcap->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
999                         return -EINVAL;
1000                 memset(cropcap, 0, sizeof(*cropcap));
1001                 cropcap->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
1002                 /* These specify the raw input of the sensor */
1003                 switch (go->standard) {
1004                 case GO7007_STD_NTSC:
1005                         cropcap->bounds.top = 0;
1006                         cropcap->bounds.left = 0;
1007                         cropcap->bounds.width = 720;
1008                         cropcap->bounds.height = 480;
1009                         cropcap->defrect.top = 0;
1010                         cropcap->defrect.left = 0;
1011                         cropcap->defrect.width = 720;
1012                         cropcap->defrect.height = 480;
1013                         break;
1014                 case GO7007_STD_PAL:
1015                         cropcap->bounds.top = 0;
1016                         cropcap->bounds.left = 0;
1017                         cropcap->bounds.width = 720;
1018                         cropcap->bounds.height = 576;
1019                         cropcap->defrect.top = 0;
1020                         cropcap->defrect.left = 0;
1021                         cropcap->defrect.width = 720;
1022                         cropcap->defrect.height = 576;
1023                         break;
1024                 case GO7007_STD_OTHER:
1025                         cropcap->bounds.top = 0;
1026                         cropcap->bounds.left = 0;
1027                         cropcap->bounds.width = go->board_info->sensor_width;
1028                         cropcap->bounds.height = go->board_info->sensor_height;
1029                         cropcap->defrect.top = 0;
1030                         cropcap->defrect.left = 0;
1031                         cropcap->defrect.width = go->board_info->sensor_width;
1032                         cropcap->defrect.height = go->board_info->sensor_height;
1033                         break;
1034                 }
1035
1036                 return 0;
1037         }
1038         case VIDIOC_G_CROP:
1039         {
1040                 struct v4l2_crop *crop = arg;
1041
1042                 if (crop->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
1043                         return -EINVAL;
1044                 memset(crop, 0, sizeof(*crop));
1045                 crop->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
1046                 /* These specify the raw input of the sensor */
1047                 switch (go->standard) {
1048                 case GO7007_STD_NTSC:
1049                         crop->c.top = 0;
1050                         crop->c.left = 0;
1051                         crop->c.width = 720;
1052                         crop->c.height = 480;
1053                         break;
1054                 case GO7007_STD_PAL:
1055                         crop->c.top = 0;
1056                         crop->c.left = 0;
1057                         crop->c.width = 720;
1058                         crop->c.height = 576;
1059                         break;
1060                 case GO7007_STD_OTHER:
1061                         crop->c.top = 0;
1062                         crop->c.left = 0;
1063                         crop->c.width = go->board_info->sensor_width;
1064                         crop->c.height = go->board_info->sensor_height;
1065                         break;
1066                 }
1067
1068                 return 0;
1069         }
1070         case VIDIOC_S_CROP:
1071         {
1072                 struct v4l2_crop *crop = arg;
1073
1074                 if (crop->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
1075                         return -EINVAL;
1076                 return 0;
1077         }
1078         case VIDIOC_G_JPEGCOMP:
1079         {
1080                 struct v4l2_jpegcompression *params = arg;
1081
1082                 memset(params, 0, sizeof(*params));
1083                 params->quality = 50; /* ?? */
1084                 params->jpeg_markers = V4L2_JPEG_MARKER_DHT |
1085                                         V4L2_JPEG_MARKER_DQT;
1086
1087                 return 0;
1088         }
1089         case VIDIOC_S_JPEGCOMP:
1090         {
1091                 struct v4l2_jpegcompression *params = arg;
1092
1093                 if (params->quality != 50 ||
1094                                 params->jpeg_markers != (V4L2_JPEG_MARKER_DHT |
1095                                                         V4L2_JPEG_MARKER_DQT))
1096                         return -EINVAL;
1097                 return 0;
1098         }
1099         /* Temporary ioctls for controlling compression characteristics */
1100         case GO7007IOC_S_BITRATE:
1101         {
1102                 int *bitrate = arg;
1103
1104                 if (go->streaming)
1105                         return -EINVAL;
1106                 /* Upper bound is kind of arbitrary here */
1107                 if (*bitrate < 64000 || *bitrate > 10000000)
1108                         return -EINVAL;
1109                 go->bitrate = *bitrate;
1110                 return 0;
1111         }
1112         case GO7007IOC_G_BITRATE:
1113         {
1114                 int *bitrate = arg;
1115
1116                 *bitrate = go->bitrate;
1117                 return 0;
1118         }
1119         case GO7007IOC_S_COMP_PARAMS:
1120         {
1121                 struct go7007_comp_params *comp = arg;
1122
1123                 if (go->format == GO7007_FORMAT_MJPEG)
1124                         return -EINVAL;
1125                 if (comp->gop_size > 0)
1126                         go->gop_size = comp->gop_size;
1127                 else
1128                         go->gop_size = go->sensor_framerate / 1000;
1129                 if (go->gop_size != 15)
1130                         go->dvd_mode = 0;
1131                 /*go->ipb = comp->max_b_frames > 0;*/ /* completely untested */
1132                 if (go->board_info->sensor_flags & GO7007_SENSOR_TV) {
1133                         switch (comp->aspect_ratio) {
1134                         case GO7007_ASPECT_RATIO_4_3_NTSC:
1135                         case GO7007_ASPECT_RATIO_4_3_PAL:
1136                                 go->aspect_ratio = GO7007_RATIO_4_3;
1137                                 break;
1138                         case GO7007_ASPECT_RATIO_16_9_NTSC:
1139                         case GO7007_ASPECT_RATIO_16_9_PAL:
1140                                 go->aspect_ratio = GO7007_RATIO_16_9;
1141                                 break;
1142                         default:
1143                                 go->aspect_ratio = GO7007_RATIO_1_1;
1144                                 break;
1145                         }
1146                 }
1147                 if (comp->flags & GO7007_COMP_OMIT_SEQ_HEADER) {
1148                         go->dvd_mode = 0;
1149                         go->seq_header_enable = 0;
1150                 } else {
1151                         go->seq_header_enable = 1;
1152                 }
1153                 /* fall-through */
1154         }
1155         case GO7007IOC_G_COMP_PARAMS:
1156         {
1157                 struct go7007_comp_params *comp = arg;
1158
1159                 if (go->format == GO7007_FORMAT_MJPEG)
1160                         return -EINVAL;
1161                 memset(comp, 0, sizeof(*comp));
1162                 comp->gop_size = go->gop_size;
1163                 comp->max_b_frames = go->ipb ? 2 : 0;
1164                 switch (go->aspect_ratio) {
1165                 case GO7007_RATIO_4_3:
1166                         if (go->standard == GO7007_STD_NTSC)
1167                                 comp->aspect_ratio =
1168                                         GO7007_ASPECT_RATIO_4_3_NTSC;
1169                         else
1170                                 comp->aspect_ratio =
1171                                         GO7007_ASPECT_RATIO_4_3_PAL;
1172                         break;
1173                 case GO7007_RATIO_16_9:
1174                         if (go->standard == GO7007_STD_NTSC)
1175                                 comp->aspect_ratio =
1176                                         GO7007_ASPECT_RATIO_16_9_NTSC;
1177                         else
1178                                 comp->aspect_ratio =
1179                                         GO7007_ASPECT_RATIO_16_9_PAL;
1180                         break;
1181                 default:
1182                         comp->aspect_ratio = GO7007_ASPECT_RATIO_1_1;
1183                         break;
1184                 }
1185                 if (go->closed_gop)
1186                         comp->flags |= GO7007_COMP_CLOSED_GOP;
1187                 if (!go->seq_header_enable)
1188                         comp->flags |= GO7007_COMP_OMIT_SEQ_HEADER;
1189                 return 0;
1190         }
1191         case GO7007IOC_S_MPEG_PARAMS:
1192         {
1193                 struct go7007_mpeg_params *mpeg = arg;
1194
1195                 if (go->format != GO7007_FORMAT_MPEG1 &&
1196                                 go->format != GO7007_FORMAT_MPEG2 &&
1197                                 go->format != GO7007_FORMAT_MPEG4)
1198                         return -EINVAL;
1199
1200                 if (mpeg->flags & GO7007_MPEG_FORCE_DVD_MODE) {
1201                         go->format = GO7007_FORMAT_MPEG2;
1202                         go->bitrate = 9800000;
1203                         go->gop_size = 15;
1204                         go->pali = 0x48;
1205                         go->closed_gop = 1;
1206                         go->repeat_seqhead = 0;
1207                         go->seq_header_enable = 1;
1208                         go->gop_header_enable = 1;
1209                         go->dvd_mode = 1;
1210                 } else {
1211                         switch (mpeg->mpeg_video_standard) {
1212                         case GO7007_MPEG_VIDEO_MPEG1:
1213                                 go->format = GO7007_FORMAT_MPEG1;
1214                                 go->pali = 0;
1215                                 break;
1216                         case GO7007_MPEG_VIDEO_MPEG2:
1217                                 go->format = GO7007_FORMAT_MPEG2;
1218                                 if (mpeg->pali >> 24 == 2)
1219                                         go->pali = mpeg->pali & 0xff;
1220                                 else
1221                                         go->pali = 0x48;
1222                                 break;
1223                         case GO7007_MPEG_VIDEO_MPEG4:
1224                                 go->format = GO7007_FORMAT_MPEG4;
1225                                 if (mpeg->pali >> 24 == 4)
1226                                         go->pali = mpeg->pali & 0xff;
1227                                 else
1228                                         go->pali = 0xf5;
1229                                 break;
1230                         default:
1231                                 return -EINVAL;
1232                         }
1233                         go->gop_header_enable =
1234                                 mpeg->flags & GO7007_MPEG_OMIT_GOP_HEADER
1235                                 ? 0 : 1;
1236                         if (mpeg->flags & GO7007_MPEG_REPEAT_SEQHEADER)
1237                                 go->repeat_seqhead = 1;
1238                         else
1239                                 go->repeat_seqhead = 0;
1240                         go->dvd_mode = 0;
1241                 }
1242                 /* fall-through */
1243         }
1244         case GO7007IOC_G_MPEG_PARAMS:
1245         {
1246                 struct go7007_mpeg_params *mpeg = arg;
1247
1248                 memset(mpeg, 0, sizeof(*mpeg));
1249                 switch (go->format) {
1250                 case GO7007_FORMAT_MPEG1:
1251                         mpeg->mpeg_video_standard = GO7007_MPEG_VIDEO_MPEG1;
1252                         mpeg->pali = 0;
1253                         break;
1254                 case GO7007_FORMAT_MPEG2:
1255                         mpeg->mpeg_video_standard = GO7007_MPEG_VIDEO_MPEG2;
1256                         mpeg->pali = GO7007_MPEG_PROFILE(2, go->pali);
1257                         break;
1258                 case GO7007_FORMAT_MPEG4:
1259                         mpeg->mpeg_video_standard = GO7007_MPEG_VIDEO_MPEG4;
1260                         mpeg->pali = GO7007_MPEG_PROFILE(4, go->pali);
1261                         break;
1262                 default:
1263                         return -EINVAL;
1264                 }
1265                 if (!go->gop_header_enable)
1266                         mpeg->flags |= GO7007_MPEG_OMIT_GOP_HEADER;
1267                 if (go->repeat_seqhead)
1268                         mpeg->flags |= GO7007_MPEG_REPEAT_SEQHEADER;
1269                 if (go->dvd_mode)
1270                         mpeg->flags |= GO7007_MPEG_FORCE_DVD_MODE;
1271                 return 0;
1272         }
1273         case GO7007IOC_S_MD_PARAMS:
1274         {
1275                 struct go7007_md_params *mdp = arg;
1276
1277                 if (mdp->region > 3)
1278                         return -EINVAL;
1279                 if (mdp->trigger > 0) {
1280                         go->modet[mdp->region].pixel_threshold =
1281                                         mdp->pixel_threshold >> 1;
1282                         go->modet[mdp->region].motion_threshold =
1283                                         mdp->motion_threshold >> 1;
1284                         go->modet[mdp->region].mb_threshold =
1285                                         mdp->trigger >> 1;
1286                         go->modet[mdp->region].enable = 1;
1287                 } else
1288                         go->modet[mdp->region].enable = 0;
1289                 /* fall-through */
1290         }
1291         case GO7007IOC_G_MD_PARAMS:
1292         {
1293                 struct go7007_md_params *mdp = arg;
1294                 int region = mdp->region;
1295
1296                 if (mdp->region > 3)
1297                         return -EINVAL;
1298                 memset(mdp, 0, sizeof(struct go7007_md_params));
1299                 mdp->region = region;
1300                 if (!go->modet[region].enable)
1301                         return 0;
1302                 mdp->pixel_threshold =
1303                         (go->modet[region].pixel_threshold << 1) + 1;
1304                 mdp->motion_threshold =
1305                         (go->modet[region].motion_threshold << 1) + 1;
1306                 mdp->trigger =
1307                         (go->modet[region].mb_threshold << 1) + 1;
1308                 return 0;
1309         }
1310         case GO7007IOC_S_MD_REGION:
1311         {
1312                 struct go7007_md_region *region = arg;
1313
1314                 if (region->region < 1 || region->region > 3)
1315                         return -EINVAL;
1316                 return clip_to_modet_map(go, region->region, region->clips);
1317         }
1318         default:
1319                 printk(KERN_DEBUG "go7007: unsupported ioctl %d\n", cmd);
1320                 return -ENOIOCTLCMD;
1321         }
1322         return 0;
1323
1324 unlock_and_return:
1325         up(&gofh->lock);
1326         return retval;
1327 }
1328
1329 static long go7007_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
1330 {
1331         struct go7007_file *gofh = file->private_data;
1332
1333         if (gofh->go->status != STATUS_ONLINE)
1334                 return -EIO;
1335
1336         return video_usercopy(file, cmd, arg, go7007_do_ioctl);
1337 }
1338
1339 static ssize_t go7007_read(struct file *file, char __user *data,
1340                 size_t count, loff_t *ppos)
1341 {
1342         return -EINVAL;
1343 }
1344
1345 static void go7007_vm_open(struct vm_area_struct *vma)
1346 {
1347         struct go7007_buffer *gobuf = vma->vm_private_data;
1348
1349         ++gobuf->mapped;
1350 }
1351
1352 static void go7007_vm_close(struct vm_area_struct *vma)
1353 {
1354         struct go7007_buffer *gobuf = vma->vm_private_data;
1355         unsigned long flags;
1356
1357         if (--gobuf->mapped == 0) {
1358                 spin_lock_irqsave(&gobuf->go->spinlock, flags);
1359                 deactivate_buffer(gobuf);
1360                 spin_unlock_irqrestore(&gobuf->go->spinlock, flags);
1361         }
1362 }
1363
1364 /* Copied from videobuf-dma-sg.c */
1365 static int go7007_vm_fault(struct vm_area_struct *vma, struct vm_fault *vmf)
1366 {
1367         struct page *page;
1368
1369         page = alloc_page(GFP_USER | __GFP_DMA32);
1370         if (!page)
1371                 return VM_FAULT_OOM;
1372         clear_user_page(page_address(page), (unsigned long)vmf->virtual_address,
1373                         page);
1374         vmf->page = page;
1375         return 0;
1376 }
1377
1378 static struct vm_operations_struct go7007_vm_ops = {
1379         .open   = go7007_vm_open,
1380         .close  = go7007_vm_close,
1381         .fault  = go7007_vm_fault,
1382 };
1383
1384 static int go7007_mmap(struct file *file, struct vm_area_struct *vma)
1385 {
1386         struct go7007_file *gofh = file->private_data;
1387         unsigned int index;
1388
1389         if (gofh->go->status != STATUS_ONLINE)
1390                 return -EIO;
1391         if (!(vma->vm_flags & VM_SHARED))
1392                 return -EINVAL; /* only support VM_SHARED mapping */
1393         if (vma->vm_end - vma->vm_start != GO7007_BUF_SIZE)
1394                 return -EINVAL; /* must map exactly one full buffer */
1395         down(&gofh->lock);
1396         index = vma->vm_pgoff / GO7007_BUF_PAGES;
1397         if (index >= gofh->buf_count) {
1398                 up(&gofh->lock);
1399                 return -EINVAL; /* trying to map beyond requested buffers */
1400         }
1401         if (index * GO7007_BUF_PAGES != vma->vm_pgoff) {
1402                 up(&gofh->lock);
1403                 return -EINVAL; /* offset is not aligned on buffer boundary */
1404         }
1405         if (gofh->bufs[index].mapped > 0) {
1406                 up(&gofh->lock);
1407                 return -EBUSY;
1408         }
1409         gofh->bufs[index].mapped = 1;
1410         gofh->bufs[index].user_addr = vma->vm_start;
1411         vma->vm_ops = &go7007_vm_ops;
1412         vma->vm_flags |= VM_DONTEXPAND;
1413         vma->vm_flags &= ~VM_IO;
1414         vma->vm_private_data = &gofh->bufs[index];
1415         up(&gofh->lock);
1416         return 0;
1417 }
1418
1419 static unsigned int go7007_poll(struct file *file, poll_table *wait)
1420 {
1421         struct go7007_file *gofh = file->private_data;
1422         struct go7007_buffer *gobuf;
1423
1424         if (list_empty(&gofh->go->stream))
1425                 return POLLERR;
1426         gobuf = list_entry(gofh->go->stream.next, struct go7007_buffer, stream);
1427         poll_wait(file, &gofh->go->frame_waitq, wait);
1428         if (gobuf->state == BUF_STATE_DONE)
1429                 return POLLIN | POLLRDNORM;
1430         return 0;
1431 }
1432
1433 static void go7007_vfl_release(struct video_device *vfd)
1434 {
1435         struct go7007 *go = video_get_drvdata(vfd);
1436
1437         video_device_release(vfd);
1438         if (--go->ref_count == 0)
1439                 kfree(go);
1440 }
1441
1442 static struct v4l2_file_operations go7007_fops = {
1443         .owner          = THIS_MODULE,
1444         .open           = go7007_open,
1445         .release        = go7007_release,
1446         .ioctl          = go7007_ioctl,
1447         .read           = go7007_read,
1448         .mmap           = go7007_mmap,
1449         .poll           = go7007_poll,
1450 };
1451
1452 static struct video_device go7007_template = {
1453         .name           = "go7007",
1454         .vfl_type       = VID_TYPE_CAPTURE,
1455         .fops           = &go7007_fops,
1456         .minor          = -1,
1457         .release        = go7007_vfl_release,
1458 };
1459
1460 int go7007_v4l2_init(struct go7007 *go)
1461 {
1462         int rv;
1463
1464         go->video_dev = video_device_alloc();
1465         if (go->video_dev == NULL)
1466                 return -ENOMEM;
1467         memcpy(go->video_dev, &go7007_template, sizeof(go7007_template));
1468         go->video_dev->parent = go->dev;
1469         rv = video_register_device(go->video_dev, VFL_TYPE_GRABBER, -1);
1470         if (rv < 0) {
1471                 video_device_release(go->video_dev);
1472                 go->video_dev = NULL;
1473                 return rv;
1474         }
1475         video_set_drvdata(go->video_dev, go);
1476         ++go->ref_count;
1477
1478         return 0;
1479 }
1480
1481 void go7007_v4l2_remove(struct go7007 *go)
1482 {
1483         unsigned long flags;
1484
1485         down(&go->hw_lock);
1486         if (go->streaming) {
1487                 go->streaming = 0;
1488                 go7007_stream_stop(go);
1489                 spin_lock_irqsave(&go->spinlock, flags);
1490                 abort_queued(go);
1491                 spin_unlock_irqrestore(&go->spinlock, flags);
1492         }
1493         up(&go->hw_lock);
1494         if (go->video_dev)
1495                 video_unregister_device(go->video_dev);
1496 }