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