Merge git://git.kernel.org/pub/scm/linux/kernel/git/davem/net-2.6
[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 inode *inode, 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 inode *inode, 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 int go7007_do_ioctl(struct inode *inode, struct file *file,
379                 unsigned int cmd, void *arg)
380 {
381         struct go7007_file *gofh = file->private_data;
382         struct go7007 *go = gofh->go;
383         unsigned long flags;
384         int retval = 0;
385
386         switch (cmd) {
387         case VIDIOC_QUERYCAP:
388         {
389                 struct v4l2_capability *cap = arg;
390
391                 memset(cap, 0, sizeof(*cap));
392                 strcpy(cap->driver, "go7007");
393                 strncpy(cap->card, go->name, sizeof(cap->card));
394                 cap->version = KERNEL_VERSION(0, 9, 8);
395                 cap->capabilities = V4L2_CAP_VIDEO_CAPTURE |
396                                 V4L2_CAP_STREAMING; /* | V4L2_CAP_AUDIO; */
397                 if (go->board_info->flags & GO7007_BOARD_HAS_TUNER)
398                         cap->capabilities |= V4L2_CAP_TUNER;
399                 return 0;
400         }
401         case VIDIOC_ENUM_FMT:
402         {
403                 struct v4l2_fmtdesc *fmt = arg;
404                 unsigned int index;
405                 char *desc;
406                 u32 pixelformat;
407
408                 if (fmt->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
409                         return -EINVAL;
410                 switch (fmt->index) {
411                 case 0:
412                         pixelformat = V4L2_PIX_FMT_MJPEG;
413                         desc = "Motion-JPEG";
414                         break;
415                 case 1:
416                         pixelformat = V4L2_PIX_FMT_MPEG;
417                         desc = "MPEG1/MPEG2/MPEG4";
418                         break;
419                 default:
420                         return -EINVAL;
421                 }
422                 index = fmt->index;
423                 memset(fmt, 0, sizeof(*fmt));
424                 fmt->index = index;
425                 fmt->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
426                 fmt->flags = V4L2_FMT_FLAG_COMPRESSED;
427                 strncpy(fmt->description, desc, sizeof(fmt->description));
428                 fmt->pixelformat = pixelformat;
429
430                 return 0;
431         }
432         case VIDIOC_TRY_FMT:
433         {
434                 struct v4l2_format *fmt = arg;
435
436                 if (fmt->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
437                         return -EINVAL;
438                 return set_capture_size(go, fmt, 1);
439         }
440         case VIDIOC_G_FMT:
441         {
442                 struct v4l2_format *fmt = arg;
443
444                 if (fmt->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
445                         return -EINVAL;
446                 memset(fmt, 0, sizeof(*fmt));
447                 fmt->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
448                 fmt->fmt.pix.width = go->width;
449                 fmt->fmt.pix.height = go->height;
450                 fmt->fmt.pix.pixelformat = go->format == GO7007_FORMAT_MJPEG ?
451                         V4L2_PIX_FMT_MJPEG : V4L2_PIX_FMT_MPEG;
452                 fmt->fmt.pix.field = V4L2_FIELD_NONE;
453                 fmt->fmt.pix.bytesperline = 0;
454                 fmt->fmt.pix.sizeimage = GO7007_BUF_SIZE;
455                 fmt->fmt.pix.colorspace = V4L2_COLORSPACE_SMPTE170M; /* ?? */
456                 return 0;
457         }
458         case VIDIOC_S_FMT:
459         {
460                 struct v4l2_format *fmt = arg;
461
462                 if (fmt->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
463                         return -EINVAL;
464                 if (go->streaming)
465                         return -EBUSY;
466                 return set_capture_size(go, fmt, 0);
467         }
468         case VIDIOC_G_FBUF:
469         case VIDIOC_S_FBUF:
470                 return -EINVAL;
471         case VIDIOC_REQBUFS:
472         {
473                 struct v4l2_requestbuffers *req = arg;
474                 unsigned int count, i;
475
476                 if (go->streaming)
477                         return -EBUSY;
478                 if (req->type != V4L2_BUF_TYPE_VIDEO_CAPTURE ||
479                                 req->memory != V4L2_MEMORY_MMAP)
480                         return -EINVAL;
481
482                 down(&gofh->lock);
483                 retval = -EBUSY;
484                 for (i = 0; i < gofh->buf_count; ++i)
485                         if (gofh->bufs[i].mapped > 0)
486                                 goto unlock_and_return;
487                 down(&go->hw_lock);
488                 if (go->in_use > 0 && gofh->buf_count == 0) {
489                         up(&go->hw_lock);
490                         goto unlock_and_return;
491                 }
492                 if (gofh->buf_count > 0)
493                         kfree(gofh->bufs);
494                 retval = -ENOMEM;
495                 count = req->count;
496                 if (count > 0) {
497                         if (count < 2)
498                                 count = 2;
499                         if (count > 32)
500                                 count = 32;
501                         gofh->bufs = kmalloc(count *
502                                                 sizeof(struct go7007_buffer),
503                                         GFP_KERNEL);
504                         if (gofh->bufs == NULL) {
505                                 up(&go->hw_lock);
506                                 goto unlock_and_return;
507                         }
508                         memset(gofh->bufs, 0,
509                                         count * sizeof(struct go7007_buffer));
510                         for (i = 0; i < count; ++i) {
511                                 gofh->bufs[i].go = go;
512                                 gofh->bufs[i].index = i;
513                                 gofh->bufs[i].state = BUF_STATE_IDLE;
514                                 gofh->bufs[i].mapped = 0;
515                         }
516                         go->in_use = 1;
517                 } else {
518                         go->in_use = 0;
519                 }
520                 gofh->buf_count = count;
521                 up(&go->hw_lock);
522                 up(&gofh->lock);
523                 memset(req, 0, sizeof(*req));
524                 req->count = count;
525                 req->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
526                 req->memory = V4L2_MEMORY_MMAP;
527                 return 0;
528         }
529         case VIDIOC_QUERYBUF:
530         {
531                 struct v4l2_buffer *buf = arg;
532                 unsigned int index;
533
534                 retval = -EINVAL;
535                 if (buf->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
536                         return -EINVAL;
537                 index = buf->index;
538                 down(&gofh->lock);
539                 if (index >= gofh->buf_count)
540                         goto unlock_and_return;
541                 memset(buf, 0, sizeof(*buf));
542                 buf->index = index;
543                 buf->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
544                 switch (gofh->bufs[index].state) {
545                 case BUF_STATE_QUEUED:
546                         buf->flags = V4L2_BUF_FLAG_QUEUED;
547                         break;
548                 case BUF_STATE_DONE:
549                         buf->flags = V4L2_BUF_FLAG_DONE;
550                         break;
551                 default:
552                         buf->flags = 0;
553                 }
554                 if (gofh->bufs[index].mapped)
555                         buf->flags |= V4L2_BUF_FLAG_MAPPED;
556                 buf->memory = V4L2_MEMORY_MMAP;
557                 buf->m.offset = index * GO7007_BUF_SIZE;
558                 buf->length = GO7007_BUF_SIZE;
559                 up(&gofh->lock);
560
561                 return 0;
562         }
563         case VIDIOC_QBUF:
564         {
565                 struct v4l2_buffer *buf = arg;
566                 struct go7007_buffer *gobuf;
567                 int ret;
568
569                 retval = -EINVAL;
570                 if (buf->type != V4L2_BUF_TYPE_VIDEO_CAPTURE ||
571                                 buf->memory != V4L2_MEMORY_MMAP)
572                         return -EINVAL;
573                 down(&gofh->lock);
574                 if (buf->index < 0 || buf->index >= gofh->buf_count)
575                         goto unlock_and_return;
576                 gobuf = &gofh->bufs[buf->index];
577                 if (gobuf->mapped == 0)
578                         goto unlock_and_return;
579                 retval = -EBUSY;
580                 if (gobuf->state != BUF_STATE_IDLE)
581                         goto unlock_and_return;
582                 /* offset will be 0 until we really support USERPTR streaming */
583                 gobuf->offset = gobuf->user_addr & ~PAGE_MASK;
584                 gobuf->bytesused = 0;
585                 gobuf->frame_offset = 0;
586                 gobuf->modet_active = 0;
587                 if (gobuf->offset > 0)
588                         gobuf->page_count = GO7007_BUF_PAGES + 1;
589                 else
590                         gobuf->page_count = GO7007_BUF_PAGES;
591                 retval = -ENOMEM;
592                 down_read(&current->mm->mmap_sem);
593                 ret = get_user_pages(current, current->mm,
594                                 gobuf->user_addr & PAGE_MASK, gobuf->page_count,
595                                 1, 1, gobuf->pages, NULL);
596                 up_read(&current->mm->mmap_sem);
597                 if (ret != gobuf->page_count) {
598                         int i;
599                         for (i = 0; i < ret; ++i)
600                                 page_cache_release(gobuf->pages[i]);
601                         gobuf->page_count = 0;
602                         goto unlock_and_return;
603                 }
604                 gobuf->state = BUF_STATE_QUEUED;
605                 spin_lock_irqsave(&go->spinlock, flags);
606                 list_add_tail(&gobuf->stream, &go->stream);
607                 spin_unlock_irqrestore(&go->spinlock, flags);
608                 up(&gofh->lock);
609                 return 0;
610         }
611         case VIDIOC_DQBUF:
612         {
613                 struct v4l2_buffer *buf = arg;
614                 struct go7007_buffer *gobuf;
615                 u32 frame_type_flag;
616                 DEFINE_WAIT(wait);
617
618                 if (buf->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
619                         return -EINVAL;
620                 if (buf->memory != V4L2_MEMORY_MMAP)
621                         return -EINVAL;
622                 down(&gofh->lock);
623                 retval = -EINVAL;
624                 if (list_empty(&go->stream))
625                         goto unlock_and_return;
626                 gobuf = list_entry(go->stream.next,
627                                 struct go7007_buffer, stream);
628                 retval = -EAGAIN;
629                 if (gobuf->state != BUF_STATE_DONE &&
630                                 !(file->f_flags & O_NONBLOCK)) {
631                         for (;;) {
632                                 prepare_to_wait(&go->frame_waitq, &wait,
633                                                 TASK_INTERRUPTIBLE);
634                                 if (gobuf->state == BUF_STATE_DONE)
635                                         break;
636                                 if (signal_pending(current)) {
637                                         retval = -ERESTARTSYS;
638                                         break;
639                                 }
640                                 schedule();
641                         }
642                         finish_wait(&go->frame_waitq, &wait);
643                 }
644                 if (gobuf->state != BUF_STATE_DONE)
645                         goto unlock_and_return;
646                 spin_lock_irqsave(&go->spinlock, flags);
647                 deactivate_buffer(gobuf);
648                 spin_unlock_irqrestore(&go->spinlock, flags);
649                 frame_type_flag = get_frame_type_flag(gobuf, go->format);
650                 gobuf->state = BUF_STATE_IDLE;
651                 memset(buf, 0, sizeof(*buf));
652                 buf->index = gobuf->index;
653                 buf->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
654                 buf->bytesused = gobuf->bytesused;
655                 buf->flags = V4L2_BUF_FLAG_MAPPED | frame_type_flag;
656                 buf->field = V4L2_FIELD_NONE;
657                 buf->timestamp = gobuf->timestamp;
658                 buf->sequence = gobuf->seq;
659                 buf->memory = V4L2_MEMORY_MMAP;
660                 buf->m.offset = gobuf->index * GO7007_BUF_SIZE;
661                 buf->length = GO7007_BUF_SIZE;
662                 buf->reserved = gobuf->modet_active;
663                 up(&gofh->lock);
664                 return 0;
665         }
666         case VIDIOC_STREAMON:
667         {
668                 unsigned int *type = arg;
669
670                 if (*type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
671                         return -EINVAL;
672                 down(&gofh->lock);
673                 down(&go->hw_lock);
674                 if (!go->streaming) {
675                         go->streaming = 1;
676                         go->next_seq = 0;
677                         go->active_buf = NULL;
678                         if (go7007_start_encoder(go) < 0)
679                                 retval = -EIO;
680                         else
681                                 retval = 0;
682                 }
683                 up(&go->hw_lock);
684                 up(&gofh->lock);
685                 return retval;
686         }
687         case VIDIOC_STREAMOFF:
688         {
689                 unsigned int *type = arg;
690
691                 if (*type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
692                         return -EINVAL;
693                 down(&gofh->lock);
694                 go7007_streamoff(go);
695                 up(&gofh->lock);
696                 return 0;
697         }
698         case VIDIOC_QUERYCTRL:
699         {
700                 struct v4l2_queryctrl *ctrl = arg;
701                 u32 id;
702
703                 if (!go->i2c_adapter_online)
704                         return -EIO;
705                 id = ctrl->id;
706                 memset(ctrl, 0, sizeof(*ctrl));
707                 ctrl->id = id;
708                 i2c_clients_command(&go->i2c_adapter, VIDIOC_QUERYCTRL, arg);
709                 return ctrl->name[0] == 0 ? -EINVAL : 0;
710         }
711         case VIDIOC_G_CTRL:
712         {
713                 struct v4l2_control *ctrl = arg;
714                 struct v4l2_queryctrl query;
715
716                 if (!go->i2c_adapter_online)
717                         return -EIO;
718                 memset(&query, 0, sizeof(query));
719                 query.id = ctrl->id;
720                 i2c_clients_command(&go->i2c_adapter, VIDIOC_QUERYCTRL, &query);
721                 if (query.name[0] == 0)
722                         return -EINVAL;
723                 i2c_clients_command(&go->i2c_adapter, VIDIOC_G_CTRL, arg);
724                 return 0;
725         }
726         case VIDIOC_S_CTRL:
727         {
728                 struct v4l2_control *ctrl = arg;
729                 struct v4l2_queryctrl query;
730
731                 if (!go->i2c_adapter_online)
732                         return -EIO;
733                 memset(&query, 0, sizeof(query));
734                 query.id = ctrl->id;
735                 i2c_clients_command(&go->i2c_adapter, VIDIOC_QUERYCTRL, &query);
736                 if (query.name[0] == 0)
737                         return -EINVAL;
738                 i2c_clients_command(&go->i2c_adapter, VIDIOC_S_CTRL, arg);
739                 return 0;
740         }
741         case VIDIOC_G_PARM:
742         {
743                 struct v4l2_streamparm *parm = arg;
744                 struct v4l2_fract timeperframe = {
745                         .numerator = 1001 *  go->fps_scale,
746                         .denominator = go->sensor_framerate,
747                 };
748
749                 if (parm->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
750                         return -EINVAL;
751                 memset(parm, 0, sizeof(*parm));
752                 parm->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
753                 parm->parm.capture.capability |= V4L2_CAP_TIMEPERFRAME;
754                 parm->parm.capture.timeperframe = timeperframe;
755                 return 0;
756         }
757         case VIDIOC_S_PARM:
758         {
759                 struct v4l2_streamparm *parm = arg;
760                 unsigned int n, d;
761
762                 if (parm->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
763                         return -EINVAL;
764                 if (parm->parm.capture.capturemode != 0)
765                         return -EINVAL;
766                 n = go->sensor_framerate *
767                         parm->parm.capture.timeperframe.numerator;
768                 d = 1001 * parm->parm.capture.timeperframe.denominator;
769                 if (n != 0 && d != 0 && n > d)
770                         go->fps_scale = (n + d/2) / d;
771                 else
772                         go->fps_scale = 1;
773                 return 0;
774         }
775         case VIDIOC_ENUMSTD:
776         {
777                 struct v4l2_standard *std = arg;
778
779                 if ((go->board_info->flags & GO7007_BOARD_HAS_TUNER) &&
780                                 go->input == go->board_info->num_inputs - 1) {
781                         if (!go->i2c_adapter_online)
782                                 return -EIO;
783                         i2c_clients_command(&go->i2c_adapter,
784                                                 VIDIOC_ENUMSTD, arg);
785                         if (!std->id) /* hack to indicate EINVAL from tuner */
786                                 return -EINVAL;
787                 } else if (go->board_info->sensor_flags & GO7007_SENSOR_TV) {
788                         switch (std->index) {
789                         case 0:
790                                 v4l2_video_std_construct(std,
791                                                 V4L2_STD_NTSC, "NTSC");
792                                 break;
793                         case 1:
794                                 v4l2_video_std_construct(std,
795                                                 V4L2_STD_PAL | V4L2_STD_SECAM,
796                                                 "PAL/SECAM");
797                                 break;
798                         default:
799                                 return -EINVAL;
800                         }
801                 } else {
802                         if (std->index != 0)
803                                 return -EINVAL;
804                         memset(std, 0, sizeof(*std));
805                         snprintf(std->name, sizeof(std->name), "%dx%d, %dfps",
806                                 go->board_info->sensor_width,
807                                 go->board_info->sensor_height,
808                                 go->board_info->sensor_framerate / 1000);
809                         std->frameperiod.numerator = 1001;
810                         std->frameperiod.denominator =
811                                         go->board_info->sensor_framerate;
812                 }
813                 return 0;
814         }
815         case VIDIOC_G_STD:
816         {
817                 v4l2_std_id *std = arg;
818
819                 if ((go->board_info->flags & GO7007_BOARD_HAS_TUNER) &&
820                                 go->input == go->board_info->num_inputs - 1) {
821                         if (!go->i2c_adapter_online)
822                                 return -EIO;
823                         i2c_clients_command(&go->i2c_adapter,
824                                                 VIDIOC_G_STD, arg);
825                 } else if (go->board_info->sensor_flags & GO7007_SENSOR_TV) {
826                         if (go->standard == GO7007_STD_NTSC)
827                                 *std = V4L2_STD_NTSC;
828                         else
829                                 *std = V4L2_STD_PAL | V4L2_STD_SECAM;
830                 } else
831                         *std = 0;
832                 return 0;
833         }
834         case VIDIOC_S_STD:
835         {
836                 v4l2_std_id *std = arg;
837
838                 if (go->streaming)
839                         return -EBUSY;
840                 if (!(go->board_info->sensor_flags & GO7007_SENSOR_TV) &&
841                                 *std != 0)
842                         return -EINVAL;
843                 if (*std == 0)
844                         return -EINVAL;
845                 if ((go->board_info->flags & GO7007_BOARD_HAS_TUNER) &&
846                                 go->input == go->board_info->num_inputs - 1) {
847                         if (!go->i2c_adapter_online)
848                                 return -EIO;
849                         i2c_clients_command(&go->i2c_adapter,
850                                                 VIDIOC_S_STD, arg);
851                         if (!*std) /* hack to indicate EINVAL from tuner */
852                                 return -EINVAL;
853                 }
854                 if (*std & V4L2_STD_NTSC) {
855                         go->standard = GO7007_STD_NTSC;
856                         go->sensor_framerate = 30000;
857                 } else if (*std & V4L2_STD_PAL) {
858                         go->standard = GO7007_STD_PAL;
859                         go->sensor_framerate = 25025;
860                 } else if (*std & V4L2_STD_SECAM) {
861                         go->standard = GO7007_STD_PAL;
862                         go->sensor_framerate = 25025;
863                 } else
864                         return -EINVAL;
865                 if (go->i2c_adapter_online)
866                         i2c_clients_command(&go->i2c_adapter,
867                                             VIDIOC_S_STD, std);
868                 set_capture_size(go, NULL, 0);
869                 return 0;
870         }
871         case VIDIOC_QUERYSTD:
872         {
873                 v4l2_std_id *std = arg;
874
875                 if ((go->board_info->flags & GO7007_BOARD_HAS_TUNER) &&
876                                 go->input == go->board_info->num_inputs - 1) {
877                         if (!go->i2c_adapter_online)
878                                 return -EIO;
879                         i2c_clients_command(&go->i2c_adapter,
880                                                 VIDIOC_QUERYSTD, arg);
881                 } else if (go->board_info->sensor_flags & GO7007_SENSOR_TV)
882                         *std = V4L2_STD_NTSC | V4L2_STD_PAL | V4L2_STD_SECAM;
883                 else
884                         *std = 0;
885                 return 0;
886         }
887         case VIDIOC_ENUMINPUT:
888         {
889                 struct v4l2_input *inp = arg;
890                 int index;
891
892                 if (inp->index >= go->board_info->num_inputs)
893                         return -EINVAL;
894                 index = inp->index;
895                 memset(inp, 0, sizeof(*inp));
896                 inp->index = index;
897                 strncpy(inp->name, go->board_info->inputs[index].name,
898                                 sizeof(inp->name));
899                 /* If this board has a tuner, it will be the last input */
900                 if ((go->board_info->flags & GO7007_BOARD_HAS_TUNER) &&
901                                 index == go->board_info->num_inputs - 1)
902                         inp->type = V4L2_INPUT_TYPE_TUNER;
903                 else
904                         inp->type = V4L2_INPUT_TYPE_CAMERA;
905                 inp->audioset = 0;
906                 inp->tuner = 0;
907                 if (go->board_info->sensor_flags & GO7007_SENSOR_TV)
908                         inp->std = V4L2_STD_NTSC | V4L2_STD_PAL |
909                                                         V4L2_STD_SECAM;
910                 else
911                         inp->std = 0;
912                 return 0;
913         }
914         case VIDIOC_G_INPUT:
915         {
916                 int *input = arg;
917
918                 *input = go->input;
919                 return 0;
920         }
921         case VIDIOC_S_INPUT:
922         {
923                 int *input = arg;
924
925                 if (*input >= go->board_info->num_inputs)
926                         return -EINVAL;
927                 if (go->streaming)
928                         return -EBUSY;
929                 go->input = *input;
930                 if (go->i2c_adapter_online) {
931                         i2c_clients_command(&go->i2c_adapter, VIDIOC_S_INPUT,
932                                 &go->board_info->inputs[*input].video_input);
933                         i2c_clients_command(&go->i2c_adapter, VIDIOC_S_AUDIO,
934                                 &go->board_info->inputs[*input].audio_input);
935                 }
936                 return 0;
937         }
938         case VIDIOC_G_TUNER:
939         {
940                 struct v4l2_tuner *t = arg;
941
942                 if (!(go->board_info->flags & GO7007_BOARD_HAS_TUNER))
943                         return -EINVAL;
944                 if (t->index != 0)
945                         return -EINVAL;
946                 if (!go->i2c_adapter_online)
947                         return -EIO;
948                 i2c_clients_command(&go->i2c_adapter, VIDIOC_G_TUNER, arg);
949                 t->index = 0;
950                 return 0;
951         }
952         case VIDIOC_S_TUNER:
953         {
954                 struct v4l2_tuner *t = arg;
955
956                 if (!(go->board_info->flags & GO7007_BOARD_HAS_TUNER))
957                         return -EINVAL;
958                 if (t->index != 0)
959                         return -EINVAL;
960                 if (!go->i2c_adapter_online)
961                         return -EIO;
962                 switch (go->board_id) {
963                 case GO7007_BOARDID_PX_TV402U_NA:
964                 case GO7007_BOARDID_PX_TV402U_JP:
965                         /* No selectable options currently */
966                         if (t->audmode != V4L2_TUNER_MODE_STEREO)
967                                 return -EINVAL;
968                         break;
969                 }
970                 i2c_clients_command(&go->i2c_adapter, VIDIOC_S_TUNER, arg);
971                 return 0;
972         }
973         case VIDIOC_G_FREQUENCY:
974         {
975                 struct v4l2_frequency *f = arg;
976
977                 if (!(go->board_info->flags & GO7007_BOARD_HAS_TUNER))
978                         return -EINVAL;
979                 if (!go->i2c_adapter_online)
980                         return -EIO;
981                 memset(f, 0, sizeof(*f));
982                 f->type = V4L2_TUNER_ANALOG_TV;
983                 i2c_clients_command(&go->i2c_adapter, VIDIOC_G_FREQUENCY, arg);
984                 return 0;
985         }
986         case VIDIOC_S_FREQUENCY:
987         {
988                 if (!(go->board_info->flags & GO7007_BOARD_HAS_TUNER))
989                         return -EINVAL;
990                 if (!go->i2c_adapter_online)
991                         return -EIO;
992                 i2c_clients_command(&go->i2c_adapter, VIDIOC_S_FREQUENCY, arg);
993                 return 0;
994         }
995         case VIDIOC_CROPCAP:
996         {
997                 struct v4l2_cropcap *cropcap = arg;
998
999                 if (cropcap->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
1000                         return -EINVAL;
1001                 memset(cropcap, 0, sizeof(*cropcap));
1002                 cropcap->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
1003                 /* These specify the raw input of the sensor */
1004                 switch (go->standard) {
1005                 case GO7007_STD_NTSC:
1006                         cropcap->bounds.top = 0;
1007                         cropcap->bounds.left = 0;
1008                         cropcap->bounds.width = 720;
1009                         cropcap->bounds.height = 480;
1010                         cropcap->defrect.top = 0;
1011                         cropcap->defrect.left = 0;
1012                         cropcap->defrect.width = 720;
1013                         cropcap->defrect.height = 480;
1014                         break;
1015                 case GO7007_STD_PAL:
1016                         cropcap->bounds.top = 0;
1017                         cropcap->bounds.left = 0;
1018                         cropcap->bounds.width = 720;
1019                         cropcap->bounds.height = 576;
1020                         cropcap->defrect.top = 0;
1021                         cropcap->defrect.left = 0;
1022                         cropcap->defrect.width = 720;
1023                         cropcap->defrect.height = 576;
1024                         break;
1025                 case GO7007_STD_OTHER:
1026                         cropcap->bounds.top = 0;
1027                         cropcap->bounds.left = 0;
1028                         cropcap->bounds.width = go->board_info->sensor_width;
1029                         cropcap->bounds.height = go->board_info->sensor_height;
1030                         cropcap->defrect.top = 0;
1031                         cropcap->defrect.left = 0;
1032                         cropcap->defrect.width = go->board_info->sensor_width;
1033                         cropcap->defrect.height = go->board_info->sensor_height;
1034                         break;
1035                 }
1036
1037                 return 0;
1038         }
1039         case VIDIOC_G_CROP:
1040         {
1041                 struct v4l2_crop *crop = arg;
1042
1043                 if (crop->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
1044                         return -EINVAL;
1045                 memset(crop, 0, sizeof(*crop));
1046                 crop->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
1047                 /* These specify the raw input of the sensor */
1048                 switch (go->standard) {
1049                 case GO7007_STD_NTSC:
1050                         crop->c.top = 0;
1051                         crop->c.left = 0;
1052                         crop->c.width = 720;
1053                         crop->c.height = 480;
1054                         break;
1055                 case GO7007_STD_PAL:
1056                         crop->c.top = 0;
1057                         crop->c.left = 0;
1058                         crop->c.width = 720;
1059                         crop->c.height = 576;
1060                         break;
1061                 case GO7007_STD_OTHER:
1062                         crop->c.top = 0;
1063                         crop->c.left = 0;
1064                         crop->c.width = go->board_info->sensor_width;
1065                         crop->c.height = go->board_info->sensor_height;
1066                         break;
1067                 }
1068
1069                 return 0;
1070         }
1071         case VIDIOC_S_CROP:
1072         {
1073                 struct v4l2_crop *crop = arg;
1074
1075                 if (crop->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
1076                         return -EINVAL;
1077                 return 0;
1078         }
1079         case VIDIOC_G_JPEGCOMP:
1080         {
1081                 struct v4l2_jpegcompression *params = arg;
1082
1083                 memset(params, 0, sizeof(*params));
1084                 params->quality = 50; /* ?? */
1085                 params->jpeg_markers = V4L2_JPEG_MARKER_DHT |
1086                                         V4L2_JPEG_MARKER_DQT;
1087
1088                 return 0;
1089         }
1090         case VIDIOC_S_JPEGCOMP:
1091         {
1092                 struct v4l2_jpegcompression *params = arg;
1093
1094                 if (params->quality != 50 ||
1095                                 params->jpeg_markers != (V4L2_JPEG_MARKER_DHT |
1096                                                         V4L2_JPEG_MARKER_DQT))
1097                         return -EINVAL;
1098                 return 0;
1099         }
1100         /* Temporary ioctls for controlling compression characteristics */
1101         case GO7007IOC_S_BITRATE:
1102         {
1103                 int *bitrate = arg;
1104
1105                 if (go->streaming)
1106                         return -EINVAL;
1107                 /* Upper bound is kind of arbitrary here */
1108                 if (*bitrate < 64000 || *bitrate > 10000000)
1109                         return -EINVAL;
1110                 go->bitrate = *bitrate;
1111                 return 0;
1112         }
1113         case GO7007IOC_G_BITRATE:
1114         {
1115                 int *bitrate = arg;
1116
1117                 *bitrate = go->bitrate;
1118                 return 0;
1119         }
1120         case GO7007IOC_S_COMP_PARAMS:
1121         {
1122                 struct go7007_comp_params *comp = arg;
1123
1124                 if (go->format == GO7007_FORMAT_MJPEG)
1125                         return -EINVAL;
1126                 if (comp->gop_size > 0)
1127                         go->gop_size = comp->gop_size;
1128                 else
1129                         go->gop_size = go->sensor_framerate / 1000;
1130                 if (go->gop_size != 15)
1131                         go->dvd_mode = 0;
1132                 /*go->ipb = comp->max_b_frames > 0;*/ /* completely untested */
1133                 if (go->board_info->sensor_flags & GO7007_SENSOR_TV) {
1134                         switch (comp->aspect_ratio) {
1135                         case GO7007_ASPECT_RATIO_4_3_NTSC:
1136                         case GO7007_ASPECT_RATIO_4_3_PAL:
1137                                 go->aspect_ratio = GO7007_RATIO_4_3;
1138                                 break;
1139                         case GO7007_ASPECT_RATIO_16_9_NTSC:
1140                         case GO7007_ASPECT_RATIO_16_9_PAL:
1141                                 go->aspect_ratio = GO7007_RATIO_16_9;
1142                                 break;
1143                         default:
1144                                 go->aspect_ratio = GO7007_RATIO_1_1;
1145                                 break;
1146                         }
1147                 }
1148                 if (comp->flags & GO7007_COMP_OMIT_SEQ_HEADER) {
1149                         go->dvd_mode = 0;
1150                         go->seq_header_enable = 0;
1151                 } else {
1152                         go->seq_header_enable = 1;
1153                 }
1154                 /* fall-through */
1155         }
1156         case GO7007IOC_G_COMP_PARAMS:
1157         {
1158                 struct go7007_comp_params *comp = arg;
1159
1160                 if (go->format == GO7007_FORMAT_MJPEG)
1161                         return -EINVAL;
1162                 memset(comp, 0, sizeof(*comp));
1163                 comp->gop_size = go->gop_size;
1164                 comp->max_b_frames = go->ipb ? 2 : 0;
1165                 switch (go->aspect_ratio) {
1166                 case GO7007_RATIO_4_3:
1167                         if (go->standard == GO7007_STD_NTSC)
1168                                 comp->aspect_ratio =
1169                                         GO7007_ASPECT_RATIO_4_3_NTSC;
1170                         else
1171                                 comp->aspect_ratio =
1172                                         GO7007_ASPECT_RATIO_4_3_PAL;
1173                         break;
1174                 case GO7007_RATIO_16_9:
1175                         if (go->standard == GO7007_STD_NTSC)
1176                                 comp->aspect_ratio =
1177                                         GO7007_ASPECT_RATIO_16_9_NTSC;
1178                         else
1179                                 comp->aspect_ratio =
1180                                         GO7007_ASPECT_RATIO_16_9_PAL;
1181                         break;
1182                 default:
1183                         comp->aspect_ratio = GO7007_ASPECT_RATIO_1_1;
1184                         break;
1185                 }
1186                 if (go->closed_gop)
1187                         comp->flags |= GO7007_COMP_CLOSED_GOP;
1188                 if (!go->seq_header_enable)
1189                         comp->flags |= GO7007_COMP_OMIT_SEQ_HEADER;
1190                 return 0;
1191         }
1192         case GO7007IOC_S_MPEG_PARAMS:
1193         {
1194                 struct go7007_mpeg_params *mpeg = arg;
1195
1196                 if (go->format != GO7007_FORMAT_MPEG1 &&
1197                                 go->format != GO7007_FORMAT_MPEG2 &&
1198                                 go->format != GO7007_FORMAT_MPEG4)
1199                         return -EINVAL;
1200
1201                 if (mpeg->flags & GO7007_MPEG_FORCE_DVD_MODE) {
1202                         go->format = GO7007_FORMAT_MPEG2;
1203                         go->bitrate = 9800000;
1204                         go->gop_size = 15;
1205                         go->pali = 0x48;
1206                         go->closed_gop = 1;
1207                         go->repeat_seqhead = 0;
1208                         go->seq_header_enable = 1;
1209                         go->gop_header_enable = 1;
1210                         go->dvd_mode = 1;
1211                 } else {
1212                         switch (mpeg->mpeg_video_standard) {
1213                         case GO7007_MPEG_VIDEO_MPEG1:
1214                                 go->format = GO7007_FORMAT_MPEG1;
1215                                 go->pali = 0;
1216                                 break;
1217                         case GO7007_MPEG_VIDEO_MPEG2:
1218                                 go->format = GO7007_FORMAT_MPEG2;
1219                                 if (mpeg->pali >> 24 == 2)
1220                                         go->pali = mpeg->pali & 0xff;
1221                                 else
1222                                         go->pali = 0x48;
1223                                 break;
1224                         case GO7007_MPEG_VIDEO_MPEG4:
1225                                 go->format = GO7007_FORMAT_MPEG4;
1226                                 if (mpeg->pali >> 24 == 4)
1227                                         go->pali = mpeg->pali & 0xff;
1228                                 else
1229                                         go->pali = 0xf5;
1230                                 break;
1231                         default:
1232                                 return -EINVAL;
1233                         }
1234                         go->gop_header_enable =
1235                                 mpeg->flags & GO7007_MPEG_OMIT_GOP_HEADER
1236                                 ? 0 : 1;
1237                         if (mpeg->flags & GO7007_MPEG_REPEAT_SEQHEADER)
1238                                 go->repeat_seqhead = 1;
1239                         else
1240                                 go->repeat_seqhead = 0;
1241                         go->dvd_mode = 0;
1242                 }
1243                 /* fall-through */
1244         }
1245         case GO7007IOC_G_MPEG_PARAMS:
1246         {
1247                 struct go7007_mpeg_params *mpeg = arg;
1248
1249                 memset(mpeg, 0, sizeof(*mpeg));
1250                 switch (go->format) {
1251                 case GO7007_FORMAT_MPEG1:
1252                         mpeg->mpeg_video_standard = GO7007_MPEG_VIDEO_MPEG1;
1253                         mpeg->pali = 0;
1254                         break;
1255                 case GO7007_FORMAT_MPEG2:
1256                         mpeg->mpeg_video_standard = GO7007_MPEG_VIDEO_MPEG2;
1257                         mpeg->pali = GO7007_MPEG_PROFILE(2, go->pali);
1258                         break;
1259                 case GO7007_FORMAT_MPEG4:
1260                         mpeg->mpeg_video_standard = GO7007_MPEG_VIDEO_MPEG4;
1261                         mpeg->pali = GO7007_MPEG_PROFILE(4, go->pali);
1262                         break;
1263                 default:
1264                         return -EINVAL;
1265                 }
1266                 if (!go->gop_header_enable)
1267                         mpeg->flags |= GO7007_MPEG_OMIT_GOP_HEADER;
1268                 if (go->repeat_seqhead)
1269                         mpeg->flags |= GO7007_MPEG_REPEAT_SEQHEADER;
1270                 if (go->dvd_mode)
1271                         mpeg->flags |= GO7007_MPEG_FORCE_DVD_MODE;
1272                 return 0;
1273         }
1274         case GO7007IOC_S_MD_PARAMS:
1275         {
1276                 struct go7007_md_params *mdp = arg;
1277
1278                 if (mdp->region > 3)
1279                         return -EINVAL;
1280                 if (mdp->trigger > 0) {
1281                         go->modet[mdp->region].pixel_threshold =
1282                                         mdp->pixel_threshold >> 1;
1283                         go->modet[mdp->region].motion_threshold =
1284                                         mdp->motion_threshold >> 1;
1285                         go->modet[mdp->region].mb_threshold =
1286                                         mdp->trigger >> 1;
1287                         go->modet[mdp->region].enable = 1;
1288                 } else
1289                         go->modet[mdp->region].enable = 0;
1290                 /* fall-through */
1291         }
1292         case GO7007IOC_G_MD_PARAMS:
1293         {
1294                 struct go7007_md_params *mdp = arg;
1295                 int region = mdp->region;
1296
1297                 if (mdp->region > 3)
1298                         return -EINVAL;
1299                 memset(mdp, 0, sizeof(struct go7007_md_params));
1300                 mdp->region = region;
1301                 if (!go->modet[region].enable)
1302                         return 0;
1303                 mdp->pixel_threshold =
1304                         (go->modet[region].pixel_threshold << 1) + 1;
1305                 mdp->motion_threshold =
1306                         (go->modet[region].motion_threshold << 1) + 1;
1307                 mdp->trigger =
1308                         (go->modet[region].mb_threshold << 1) + 1;
1309                 return 0;
1310         }
1311         case GO7007IOC_S_MD_REGION:
1312         {
1313                 struct go7007_md_region *region = arg;
1314
1315                 if (region->region < 1 || region->region > 3)
1316                         return -EINVAL;
1317                 return clip_to_modet_map(go, region->region, region->clips);
1318         }
1319         default:
1320                 printk(KERN_DEBUG "go7007: unsupported ioctl %d\n", cmd);
1321                 return -ENOIOCTLCMD;
1322         }
1323         return 0;
1324
1325 unlock_and_return:
1326         up(&gofh->lock);
1327         return retval;
1328 }
1329
1330 static int go7007_ioctl(struct inode *inode, struct file *file,
1331                 unsigned int cmd, unsigned long arg)
1332 {
1333         struct go7007_file *gofh = file->private_data;
1334
1335         if (gofh->go->status != STATUS_ONLINE)
1336                 return -EIO;
1337
1338         return video_usercopy(inode, file, cmd, arg, go7007_do_ioctl);
1339 }
1340
1341 static ssize_t go7007_read(struct file *file, char __user *data,
1342                 size_t count, loff_t *ppos)
1343 {
1344         return -EINVAL;
1345 }
1346
1347 static void go7007_vm_open(struct vm_area_struct *vma)
1348 {
1349         struct go7007_buffer *gobuf = vma->vm_private_data;
1350
1351         ++gobuf->mapped;
1352 }
1353
1354 static void go7007_vm_close(struct vm_area_struct *vma)
1355 {
1356         struct go7007_buffer *gobuf = vma->vm_private_data;
1357         unsigned long flags;
1358
1359         if (--gobuf->mapped == 0) {
1360                 spin_lock_irqsave(&gobuf->go->spinlock, flags);
1361                 deactivate_buffer(gobuf);
1362                 spin_unlock_irqrestore(&gobuf->go->spinlock, flags);
1363         }
1364 }
1365
1366 /* Copied from videobuf-dma-sg.c */
1367 static int go7007_vm_fault(struct vm_area_struct *vma, struct vm_fault *vmf)
1368 {
1369         struct page *page;
1370
1371         page = alloc_page(GFP_USER | __GFP_DMA32);
1372         if (!page)
1373                 return VM_FAULT_OOM;
1374         clear_user_page(page_address(page), (unsigned long)vmf->virtual_address,
1375                         page);
1376         vmf->page = page;
1377         return 0;
1378 }
1379
1380 static struct vm_operations_struct go7007_vm_ops = {
1381         .open   = go7007_vm_open,
1382         .close  = go7007_vm_close,
1383         .fault  = go7007_vm_fault,
1384 };
1385
1386 static int go7007_mmap(struct file *file, struct vm_area_struct *vma)
1387 {
1388         struct go7007_file *gofh = file->private_data;
1389         unsigned int index;
1390
1391         if (gofh->go->status != STATUS_ONLINE)
1392                 return -EIO;
1393         if (!(vma->vm_flags & VM_SHARED))
1394                 return -EINVAL; /* only support VM_SHARED mapping */
1395         if (vma->vm_end - vma->vm_start != GO7007_BUF_SIZE)
1396                 return -EINVAL; /* must map exactly one full buffer */
1397         down(&gofh->lock);
1398         index = vma->vm_pgoff / GO7007_BUF_PAGES;
1399         if (index >= gofh->buf_count) {
1400                 up(&gofh->lock);
1401                 return -EINVAL; /* trying to map beyond requested buffers */
1402         }
1403         if (index * GO7007_BUF_PAGES != vma->vm_pgoff) {
1404                 up(&gofh->lock);
1405                 return -EINVAL; /* offset is not aligned on buffer boundary */
1406         }
1407         if (gofh->bufs[index].mapped > 0) {
1408                 up(&gofh->lock);
1409                 return -EBUSY;
1410         }
1411         gofh->bufs[index].mapped = 1;
1412         gofh->bufs[index].user_addr = vma->vm_start;
1413         vma->vm_ops = &go7007_vm_ops;
1414         vma->vm_flags |= VM_DONTEXPAND;
1415         vma->vm_flags &= ~VM_IO;
1416         vma->vm_private_data = &gofh->bufs[index];
1417         up(&gofh->lock);
1418         return 0;
1419 }
1420
1421 static unsigned int go7007_poll(struct file *file, poll_table *wait)
1422 {
1423         struct go7007_file *gofh = file->private_data;
1424         struct go7007_buffer *gobuf;
1425
1426         if (list_empty(&gofh->go->stream))
1427                 return POLLERR;
1428         gobuf = list_entry(gofh->go->stream.next, struct go7007_buffer, stream);
1429         poll_wait(file, &gofh->go->frame_waitq, wait);
1430         if (gobuf->state == BUF_STATE_DONE)
1431                 return POLLIN | POLLRDNORM;
1432         return 0;
1433 }
1434
1435 static void go7007_vfl_release(struct video_device *vfd)
1436 {
1437         struct go7007 *go = video_get_drvdata(vfd);
1438
1439         video_device_release(vfd);
1440         if (--go->ref_count == 0)
1441                 kfree(go);
1442 }
1443
1444 static struct file_operations go7007_fops = {
1445         .owner          = THIS_MODULE,
1446         .open           = go7007_open,
1447         .release        = go7007_release,
1448         .ioctl          = go7007_ioctl,
1449         .llseek         = no_llseek,
1450         .read           = go7007_read,
1451         .mmap           = go7007_mmap,
1452         .poll           = go7007_poll,
1453 };
1454
1455 static struct video_device go7007_template = {
1456         .name           = "go7007",
1457         .vfl_type       = VID_TYPE_CAPTURE,
1458         .fops           = &go7007_fops,
1459         .minor          = -1,
1460         .release        = go7007_vfl_release,
1461 };
1462
1463 int go7007_v4l2_init(struct go7007 *go)
1464 {
1465         int rv;
1466
1467         go->video_dev = video_device_alloc();
1468         if (go->video_dev == NULL)
1469                 return -ENOMEM;
1470         memcpy(go->video_dev, &go7007_template, sizeof(go7007_template));
1471         go->video_dev->parent = go->dev;
1472         rv = video_register_device(go->video_dev, VFL_TYPE_GRABBER, -1);
1473         if (rv < 0) {
1474                 video_device_release(go->video_dev);
1475                 go->video_dev = NULL;
1476                 return rv;
1477         }
1478         video_set_drvdata(go->video_dev, go);
1479         ++go->ref_count;
1480
1481         return 0;
1482 }
1483
1484 void go7007_v4l2_remove(struct go7007 *go)
1485 {
1486         unsigned long flags;
1487
1488         down(&go->hw_lock);
1489         if (go->streaming) {
1490                 go->streaming = 0;
1491                 go7007_stream_stop(go);
1492                 spin_lock_irqsave(&go->spinlock, flags);
1493                 abort_queued(go);
1494                 spin_unlock_irqrestore(&go->spinlock, flags);
1495         }
1496         up(&go->hw_lock);
1497         if (go->video_dev)
1498                 video_unregister_device(go->video_dev);
1499 }