• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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/delay.h>
21 #include <linux/sched.h>
22 #include <linux/spinlock.h>
23 #include <linux/slab.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/i2c.h>
30 #include <linux/mutex.h>
31 #include <linux/uaccess.h>
32 #include <linux/videodev2.h>
33 #include <media/v4l2-common.h>
34 #include <media/v4l2-ioctl.h>
35 #include <media/v4l2-subdev.h>
36 #include <media/v4l2-event.h>
37 #include <media/videobuf2-vmalloc.h>
38 #include <media/saa7115.h>
39 
40 #include "go7007.h"
41 #include "go7007-priv.h"
42 
43 #define call_all(dev, o, f, args...) \
44 	v4l2_device_call_until_err(dev, 0, o, f, ##args)
45 
valid_pixelformat(u32 pixelformat)46 static bool valid_pixelformat(u32 pixelformat)
47 {
48 	switch (pixelformat) {
49 	case V4L2_PIX_FMT_MJPEG:
50 	case V4L2_PIX_FMT_MPEG1:
51 	case V4L2_PIX_FMT_MPEG2:
52 	case V4L2_PIX_FMT_MPEG4:
53 		return true;
54 	default:
55 		return false;
56 	}
57 }
58 
get_frame_type_flag(struct go7007_buffer * vb,int format)59 static u32 get_frame_type_flag(struct go7007_buffer *vb, int format)
60 {
61 	u8 *ptr = vb2_plane_vaddr(&vb->vb, 0);
62 
63 	switch (format) {
64 	case V4L2_PIX_FMT_MJPEG:
65 		return V4L2_BUF_FLAG_KEYFRAME;
66 	case V4L2_PIX_FMT_MPEG4:
67 		switch ((ptr[vb->frame_offset + 4] >> 6) & 0x3) {
68 		case 0:
69 			return V4L2_BUF_FLAG_KEYFRAME;
70 		case 1:
71 			return V4L2_BUF_FLAG_PFRAME;
72 		case 2:
73 			return V4L2_BUF_FLAG_BFRAME;
74 		default:
75 			return 0;
76 		}
77 	case V4L2_PIX_FMT_MPEG1:
78 	case V4L2_PIX_FMT_MPEG2:
79 		switch ((ptr[vb->frame_offset + 5] >> 3) & 0x7) {
80 		case 1:
81 			return V4L2_BUF_FLAG_KEYFRAME;
82 		case 2:
83 			return V4L2_BUF_FLAG_PFRAME;
84 		case 3:
85 			return V4L2_BUF_FLAG_BFRAME;
86 		default:
87 			return 0;
88 		}
89 	}
90 
91 	return 0;
92 }
93 
get_resolution(struct go7007 * go,int * width,int * height)94 static void get_resolution(struct go7007 *go, int *width, int *height)
95 {
96 	switch (go->standard) {
97 	case GO7007_STD_NTSC:
98 		*width = 720;
99 		*height = 480;
100 		break;
101 	case GO7007_STD_PAL:
102 		*width = 720;
103 		*height = 576;
104 		break;
105 	case GO7007_STD_OTHER:
106 	default:
107 		*width = go->board_info->sensor_width;
108 		*height = go->board_info->sensor_height;
109 		break;
110 	}
111 }
112 
set_formatting(struct go7007 * go)113 static void set_formatting(struct go7007 *go)
114 {
115 	if (go->format == V4L2_PIX_FMT_MJPEG) {
116 		go->pali = 0;
117 		go->aspect_ratio = GO7007_RATIO_1_1;
118 		go->gop_size = 0;
119 		go->ipb = 0;
120 		go->closed_gop = 0;
121 		go->repeat_seqhead = 0;
122 		go->seq_header_enable = 0;
123 		go->gop_header_enable = 0;
124 		go->dvd_mode = 0;
125 		return;
126 	}
127 
128 	switch (go->format) {
129 	case V4L2_PIX_FMT_MPEG1:
130 		go->pali = 0;
131 		break;
132 	default:
133 	case V4L2_PIX_FMT_MPEG2:
134 		go->pali = 0x48;
135 		break;
136 	case V4L2_PIX_FMT_MPEG4:
137 		/* For future reference: this is the list of MPEG4
138 		 * profiles that are available, although they are
139 		 * untested:
140 		 *
141 		 * Profile		pali
142 		 * --------------	----
143 		 * PROFILE_S_L0		0x08
144 		 * PROFILE_S_L1		0x01
145 		 * PROFILE_S_L2		0x02
146 		 * PROFILE_S_L3		0x03
147 		 * PROFILE_ARTS_L1	0x91
148 		 * PROFILE_ARTS_L2	0x92
149 		 * PROFILE_ARTS_L3	0x93
150 		 * PROFILE_ARTS_L4	0x94
151 		 * PROFILE_AS_L0	0xf0
152 		 * PROFILE_AS_L1	0xf1
153 		 * PROFILE_AS_L2	0xf2
154 		 * PROFILE_AS_L3	0xf3
155 		 * PROFILE_AS_L4	0xf4
156 		 * PROFILE_AS_L5	0xf5
157 		 */
158 		go->pali = 0xf5;
159 		break;
160 	}
161 	go->gop_size = v4l2_ctrl_g_ctrl(go->mpeg_video_gop_size);
162 	go->closed_gop = v4l2_ctrl_g_ctrl(go->mpeg_video_gop_closure);
163 	go->ipb = v4l2_ctrl_g_ctrl(go->mpeg_video_b_frames) != 0;
164 	go->bitrate = v4l2_ctrl_g_ctrl(go->mpeg_video_bitrate);
165 	go->repeat_seqhead = v4l2_ctrl_g_ctrl(go->mpeg_video_rep_seqheader);
166 	go->gop_header_enable = 1;
167 	go->dvd_mode = 0;
168 	if (go->format == V4L2_PIX_FMT_MPEG2)
169 		go->dvd_mode =
170 			go->bitrate == 9800000 &&
171 			go->gop_size == 15 &&
172 			go->ipb == 0 &&
173 			go->repeat_seqhead == 1 &&
174 			go->closed_gop;
175 
176 	switch (v4l2_ctrl_g_ctrl(go->mpeg_video_aspect_ratio)) {
177 	default:
178 	case V4L2_MPEG_VIDEO_ASPECT_1x1:
179 		go->aspect_ratio = GO7007_RATIO_1_1;
180 		break;
181 	case V4L2_MPEG_VIDEO_ASPECT_4x3:
182 		go->aspect_ratio = GO7007_RATIO_4_3;
183 		break;
184 	case V4L2_MPEG_VIDEO_ASPECT_16x9:
185 		go->aspect_ratio = GO7007_RATIO_16_9;
186 		break;
187 	}
188 }
189 
set_capture_size(struct go7007 * go,struct v4l2_format * fmt,int try)190 static int set_capture_size(struct go7007 *go, struct v4l2_format *fmt, int try)
191 {
192 	int sensor_height = 0, sensor_width = 0;
193 	int width, height, i;
194 
195 	if (fmt != NULL && !valid_pixelformat(fmt->fmt.pix.pixelformat))
196 		return -EINVAL;
197 
198 	get_resolution(go, &sensor_width, &sensor_height);
199 
200 	if (fmt == NULL) {
201 		width = sensor_width;
202 		height = sensor_height;
203 	} else if (go->board_info->sensor_flags & GO7007_SENSOR_SCALING) {
204 		if (fmt->fmt.pix.width > sensor_width)
205 			width = sensor_width;
206 		else if (fmt->fmt.pix.width < 144)
207 			width = 144;
208 		else
209 			width = fmt->fmt.pix.width & ~0x0f;
210 
211 		if (fmt->fmt.pix.height > sensor_height)
212 			height = sensor_height;
213 		else if (fmt->fmt.pix.height < 96)
214 			height = 96;
215 		else
216 			height = fmt->fmt.pix.height & ~0x0f;
217 	} else {
218 		width = fmt->fmt.pix.width;
219 
220 		if (width <= sensor_width / 4) {
221 			width = sensor_width / 4;
222 			height = sensor_height / 4;
223 		} else if (width <= sensor_width / 2) {
224 			width = sensor_width / 2;
225 			height = sensor_height / 2;
226 		} else {
227 			width = sensor_width;
228 			height = sensor_height;
229 		}
230 		width &= ~0xf;
231 		height &= ~0xf;
232 	}
233 
234 	if (fmt != NULL) {
235 		u32 pixelformat = fmt->fmt.pix.pixelformat;
236 
237 		memset(fmt, 0, sizeof(*fmt));
238 		fmt->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
239 		fmt->fmt.pix.width = width;
240 		fmt->fmt.pix.height = height;
241 		fmt->fmt.pix.pixelformat = pixelformat;
242 		fmt->fmt.pix.field = V4L2_FIELD_NONE;
243 		fmt->fmt.pix.bytesperline = 0;
244 		fmt->fmt.pix.sizeimage = GO7007_BUF_SIZE;
245 		fmt->fmt.pix.colorspace = V4L2_COLORSPACE_SMPTE170M;
246 	}
247 
248 	if (try)
249 		return 0;
250 
251 	if (fmt)
252 		go->format = fmt->fmt.pix.pixelformat;
253 	go->width = width;
254 	go->height = height;
255 	go->encoder_h_offset = go->board_info->sensor_h_offset;
256 	go->encoder_v_offset = go->board_info->sensor_v_offset;
257 	for (i = 0; i < 4; ++i)
258 		go->modet[i].enable = 0;
259 	for (i = 0; i < 1624; ++i)
260 		go->modet_map[i] = 0;
261 
262 	if (go->board_info->sensor_flags & GO7007_SENSOR_SCALING) {
263 		struct v4l2_mbus_framefmt mbus_fmt;
264 
265 		mbus_fmt.code = V4L2_MBUS_FMT_FIXED;
266 		mbus_fmt.width = fmt ? fmt->fmt.pix.width : width;
267 		mbus_fmt.height = height;
268 		go->encoder_h_halve = 0;
269 		go->encoder_v_halve = 0;
270 		go->encoder_subsample = 0;
271 		call_all(&go->v4l2_dev, video, s_mbus_fmt, &mbus_fmt);
272 	} else {
273 		if (width <= sensor_width / 4) {
274 			go->encoder_h_halve = 1;
275 			go->encoder_v_halve = 1;
276 			go->encoder_subsample = 1;
277 		} else if (width <= sensor_width / 2) {
278 			go->encoder_h_halve = 1;
279 			go->encoder_v_halve = 1;
280 			go->encoder_subsample = 0;
281 		} else {
282 			go->encoder_h_halve = 0;
283 			go->encoder_v_halve = 0;
284 			go->encoder_subsample = 0;
285 		}
286 	}
287 	return 0;
288 }
289 
290 #if 0
291 static int clip_to_modet_map(struct go7007 *go, int region,
292 		struct v4l2_clip *clip_list)
293 {
294 	struct v4l2_clip clip, *clip_ptr;
295 	int x, y, mbnum;
296 
297 	/* Check if coordinates are OK and if any macroblocks are already
298 	 * used by other regions (besides 0) */
299 	clip_ptr = clip_list;
300 	while (clip_ptr) {
301 		if (copy_from_user(&clip, clip_ptr, sizeof(clip)))
302 			return -EFAULT;
303 		if (clip.c.left < 0 || (clip.c.left & 0xF) ||
304 				clip.c.width <= 0 || (clip.c.width & 0xF))
305 			return -EINVAL;
306 		if (clip.c.left + clip.c.width > go->width)
307 			return -EINVAL;
308 		if (clip.c.top < 0 || (clip.c.top & 0xF) ||
309 				clip.c.height <= 0 || (clip.c.height & 0xF))
310 			return -EINVAL;
311 		if (clip.c.top + clip.c.height > go->height)
312 			return -EINVAL;
313 		for (y = 0; y < clip.c.height; y += 16)
314 			for (x = 0; x < clip.c.width; x += 16) {
315 				mbnum = (go->width >> 4) *
316 						((clip.c.top + y) >> 4) +
317 					((clip.c.left + x) >> 4);
318 				if (go->modet_map[mbnum] != 0 &&
319 						go->modet_map[mbnum] != region)
320 					return -EBUSY;
321 			}
322 		clip_ptr = clip.next;
323 	}
324 
325 	/* Clear old region macroblocks */
326 	for (mbnum = 0; mbnum < 1624; ++mbnum)
327 		if (go->modet_map[mbnum] == region)
328 			go->modet_map[mbnum] = 0;
329 
330 	/* Claim macroblocks in this list */
331 	clip_ptr = clip_list;
332 	while (clip_ptr) {
333 		if (copy_from_user(&clip, clip_ptr, sizeof(clip)))
334 			return -EFAULT;
335 		for (y = 0; y < clip.c.height; y += 16)
336 			for (x = 0; x < clip.c.width; x += 16) {
337 				mbnum = (go->width >> 4) *
338 						((clip.c.top + y) >> 4) +
339 					((clip.c.left + x) >> 4);
340 				go->modet_map[mbnum] = region;
341 			}
342 		clip_ptr = clip.next;
343 	}
344 	return 0;
345 }
346 #endif
347 
vidioc_querycap(struct file * file,void * priv,struct v4l2_capability * cap)348 static int vidioc_querycap(struct file *file, void  *priv,
349 					struct v4l2_capability *cap)
350 {
351 	struct go7007 *go = video_drvdata(file);
352 
353 	strlcpy(cap->driver, "go7007", sizeof(cap->driver));
354 	strlcpy(cap->card, go->name, sizeof(cap->card));
355 	strlcpy(cap->bus_info, go->bus_info, sizeof(cap->bus_info));
356 
357 	cap->device_caps = V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_READWRITE |
358 				V4L2_CAP_STREAMING;
359 
360 	if (go->board_info->num_aud_inputs)
361 		cap->device_caps |= V4L2_CAP_AUDIO;
362 	if (go->board_info->flags & GO7007_BOARD_HAS_TUNER)
363 		cap->device_caps |= V4L2_CAP_TUNER;
364 	cap->capabilities = cap->device_caps | V4L2_CAP_DEVICE_CAPS;
365 	return 0;
366 }
367 
vidioc_enum_fmt_vid_cap(struct file * file,void * priv,struct v4l2_fmtdesc * fmt)368 static int vidioc_enum_fmt_vid_cap(struct file *file, void  *priv,
369 					struct v4l2_fmtdesc *fmt)
370 {
371 	char *desc = NULL;
372 
373 	switch (fmt->index) {
374 	case 0:
375 		fmt->pixelformat = V4L2_PIX_FMT_MJPEG;
376 		desc = "Motion JPEG";
377 		break;
378 	case 1:
379 		fmt->pixelformat = V4L2_PIX_FMT_MPEG1;
380 		desc = "MPEG-1 ES";
381 		break;
382 	case 2:
383 		fmt->pixelformat = V4L2_PIX_FMT_MPEG2;
384 		desc = "MPEG-2 ES";
385 		break;
386 	case 3:
387 		fmt->pixelformat = V4L2_PIX_FMT_MPEG4;
388 		desc = "MPEG-4 ES";
389 		break;
390 	default:
391 		return -EINVAL;
392 	}
393 	fmt->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
394 	fmt->flags = V4L2_FMT_FLAG_COMPRESSED;
395 
396 	strncpy(fmt->description, desc, sizeof(fmt->description));
397 
398 	return 0;
399 }
400 
vidioc_g_fmt_vid_cap(struct file * file,void * priv,struct v4l2_format * fmt)401 static int vidioc_g_fmt_vid_cap(struct file *file, void *priv,
402 					struct v4l2_format *fmt)
403 {
404 	struct go7007 *go = video_drvdata(file);
405 
406 	fmt->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
407 	fmt->fmt.pix.width = go->width;
408 	fmt->fmt.pix.height = go->height;
409 	fmt->fmt.pix.pixelformat = go->format;
410 	fmt->fmt.pix.field = V4L2_FIELD_NONE;
411 	fmt->fmt.pix.bytesperline = 0;
412 	fmt->fmt.pix.sizeimage = GO7007_BUF_SIZE;
413 	fmt->fmt.pix.colorspace = V4L2_COLORSPACE_SMPTE170M;
414 
415 	return 0;
416 }
417 
vidioc_try_fmt_vid_cap(struct file * file,void * priv,struct v4l2_format * fmt)418 static int vidioc_try_fmt_vid_cap(struct file *file, void *priv,
419 			struct v4l2_format *fmt)
420 {
421 	struct go7007 *go = video_drvdata(file);
422 
423 	return set_capture_size(go, fmt, 1);
424 }
425 
vidioc_s_fmt_vid_cap(struct file * file,void * priv,struct v4l2_format * fmt)426 static int vidioc_s_fmt_vid_cap(struct file *file, void *priv,
427 			struct v4l2_format *fmt)
428 {
429 	struct go7007 *go = video_drvdata(file);
430 
431 	if (vb2_is_busy(&go->vidq))
432 		return -EBUSY;
433 
434 	return set_capture_size(go, fmt, 0);
435 }
436 
go7007_queue_setup(struct vb2_queue * q,const struct v4l2_format * fmt,unsigned int * num_buffers,unsigned int * num_planes,unsigned int sizes[],void * alloc_ctxs[])437 static int go7007_queue_setup(struct vb2_queue *q, const struct v4l2_format *fmt,
438 		unsigned int *num_buffers, unsigned int *num_planes,
439 		unsigned int sizes[], void *alloc_ctxs[])
440 {
441 	sizes[0] = GO7007_BUF_SIZE;
442 	*num_planes = 1;
443 
444 	if (*num_buffers < 2)
445 		*num_buffers = 2;
446 
447 	return 0;
448 }
449 
go7007_buf_queue(struct vb2_buffer * vb)450 static void go7007_buf_queue(struct vb2_buffer *vb)
451 {
452 	struct vb2_queue *vq = vb->vb2_queue;
453 	struct go7007 *go = vb2_get_drv_priv(vq);
454 	struct go7007_buffer *go7007_vb =
455 		container_of(vb, struct go7007_buffer, vb);
456 	unsigned long flags;
457 
458 	spin_lock_irqsave(&go->spinlock, flags);
459 	list_add_tail(&go7007_vb->list, &go->vidq_active);
460 	spin_unlock_irqrestore(&go->spinlock, flags);
461 }
462 
go7007_buf_prepare(struct vb2_buffer * vb)463 static int go7007_buf_prepare(struct vb2_buffer *vb)
464 {
465 	struct go7007_buffer *go7007_vb =
466 		container_of(vb, struct go7007_buffer, vb);
467 
468 	go7007_vb->modet_active = 0;
469 	go7007_vb->frame_offset = 0;
470 	vb->v4l2_planes[0].bytesused = 0;
471 	return 0;
472 }
473 
go7007_buf_finish(struct vb2_buffer * vb)474 static int go7007_buf_finish(struct vb2_buffer *vb)
475 {
476 	struct vb2_queue *vq = vb->vb2_queue;
477 	struct go7007 *go = vb2_get_drv_priv(vq);
478 	struct go7007_buffer *go7007_vb =
479 		container_of(vb, struct go7007_buffer, vb);
480 	u32 frame_type_flag = get_frame_type_flag(go7007_vb, go->format);
481 	struct v4l2_buffer *buf = &vb->v4l2_buf;
482 
483 	buf->flags &= ~(V4L2_BUF_FLAG_KEYFRAME | V4L2_BUF_FLAG_BFRAME |
484 			V4L2_BUF_FLAG_PFRAME);
485 	buf->flags |= frame_type_flag;
486 	buf->field = V4L2_FIELD_NONE;
487 	return 0;
488 }
489 
go7007_start_streaming(struct vb2_queue * q,unsigned int count)490 static int go7007_start_streaming(struct vb2_queue *q, unsigned int count)
491 {
492 	struct go7007 *go = vb2_get_drv_priv(q);
493 	int ret;
494 
495 	set_formatting(go);
496 	mutex_lock(&go->hw_lock);
497 	go->next_seq = 0;
498 	go->active_buf = NULL;
499 	q->streaming = 1;
500 	if (go7007_start_encoder(go) < 0)
501 		ret = -EIO;
502 	else
503 		ret = 0;
504 	mutex_unlock(&go->hw_lock);
505 	if (ret) {
506 		q->streaming = 0;
507 		return ret;
508 	}
509 	call_all(&go->v4l2_dev, video, s_stream, 1);
510 	v4l2_ctrl_grab(go->mpeg_video_gop_size, true);
511 	v4l2_ctrl_grab(go->mpeg_video_gop_closure, true);
512 	v4l2_ctrl_grab(go->mpeg_video_bitrate, true);
513 	v4l2_ctrl_grab(go->mpeg_video_aspect_ratio, true);
514 	/* Turn on Capture LED */
515 	if (go->board_id == GO7007_BOARDID_ADS_USBAV_709)
516 		go7007_write_addr(go, 0x3c82, 0x0005);
517 	return ret;
518 }
519 
go7007_stop_streaming(struct vb2_queue * q)520 static int go7007_stop_streaming(struct vb2_queue *q)
521 {
522 	struct go7007 *go = vb2_get_drv_priv(q);
523 	unsigned long flags;
524 
525 	q->streaming = 0;
526 	go7007_stream_stop(go);
527 	mutex_lock(&go->hw_lock);
528 	go7007_reset_encoder(go);
529 	mutex_unlock(&go->hw_lock);
530 	call_all(&go->v4l2_dev, video, s_stream, 0);
531 
532 	spin_lock_irqsave(&go->spinlock, flags);
533 	INIT_LIST_HEAD(&go->vidq_active);
534 	spin_unlock_irqrestore(&go->spinlock, flags);
535 	v4l2_ctrl_grab(go->mpeg_video_gop_size, false);
536 	v4l2_ctrl_grab(go->mpeg_video_gop_closure, false);
537 	v4l2_ctrl_grab(go->mpeg_video_bitrate, false);
538 	v4l2_ctrl_grab(go->mpeg_video_aspect_ratio, false);
539 	/* Turn on Capture LED */
540 	if (go->board_id == GO7007_BOARDID_ADS_USBAV_709)
541 		go7007_write_addr(go, 0x3c82, 0x000d);
542 	return 0;
543 }
544 
545 static struct vb2_ops go7007_video_qops = {
546 	.queue_setup    = go7007_queue_setup,
547 	.buf_queue      = go7007_buf_queue,
548 	.buf_prepare    = go7007_buf_prepare,
549 	.buf_finish     = go7007_buf_finish,
550 	.start_streaming = go7007_start_streaming,
551 	.stop_streaming = go7007_stop_streaming,
552 	.wait_prepare   = vb2_ops_wait_prepare,
553 	.wait_finish    = vb2_ops_wait_finish,
554 };
555 
vidioc_g_parm(struct file * filp,void * priv,struct v4l2_streamparm * parm)556 static int vidioc_g_parm(struct file *filp, void *priv,
557 		struct v4l2_streamparm *parm)
558 {
559 	struct go7007 *go = video_drvdata(filp);
560 	struct v4l2_fract timeperframe = {
561 		.numerator = 1001 *  go->fps_scale,
562 		.denominator = go->sensor_framerate,
563 	};
564 
565 	if (parm->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
566 		return -EINVAL;
567 
568 	parm->parm.capture.readbuffers = 2;
569 	parm->parm.capture.capability = V4L2_CAP_TIMEPERFRAME;
570 	parm->parm.capture.timeperframe = timeperframe;
571 
572 	return 0;
573 }
574 
vidioc_s_parm(struct file * filp,void * priv,struct v4l2_streamparm * parm)575 static int vidioc_s_parm(struct file *filp, void *priv,
576 		struct v4l2_streamparm *parm)
577 {
578 	struct go7007 *go = video_drvdata(filp);
579 	unsigned int n, d;
580 
581 	if (parm->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
582 		return -EINVAL;
583 
584 	n = go->sensor_framerate *
585 		parm->parm.capture.timeperframe.numerator;
586 	d = 1001 * parm->parm.capture.timeperframe.denominator;
587 	if (n != 0 && d != 0 && n > d)
588 		go->fps_scale = (n + d/2) / d;
589 	else
590 		go->fps_scale = 1;
591 
592 	return vidioc_g_parm(filp, priv, parm);
593 }
594 
595 /* VIDIOC_ENUMSTD on go7007 were used for enumerating the supported fps and
596    its resolution, when the device is not connected to TV.
597    This is were an API abuse, probably used by the lack of specific IOCTL's to
598    enumerate it, by the time the driver was written.
599 
600    However, since kernel 2.6.19, two new ioctls (VIDIOC_ENUM_FRAMEINTERVALS
601    and VIDIOC_ENUM_FRAMESIZES) were added for this purpose.
602 
603    The two functions below implement the newer ioctls
604 */
vidioc_enum_framesizes(struct file * filp,void * priv,struct v4l2_frmsizeenum * fsize)605 static int vidioc_enum_framesizes(struct file *filp, void *priv,
606 				  struct v4l2_frmsizeenum *fsize)
607 {
608 	struct go7007 *go = video_drvdata(filp);
609 	int width, height;
610 
611 	if (fsize->index > 2)
612 		return -EINVAL;
613 
614 	if (!valid_pixelformat(fsize->pixel_format))
615 		return -EINVAL;
616 
617 	get_resolution(go, &width, &height);
618 	fsize->type = V4L2_FRMSIZE_TYPE_DISCRETE;
619 	fsize->discrete.width = (width >> fsize->index) & ~0xf;
620 	fsize->discrete.height = (height >> fsize->index) & ~0xf;
621 	return 0;
622 }
623 
vidioc_enum_frameintervals(struct file * filp,void * priv,struct v4l2_frmivalenum * fival)624 static int vidioc_enum_frameintervals(struct file *filp, void *priv,
625 				      struct v4l2_frmivalenum *fival)
626 {
627 	struct go7007 *go = video_drvdata(filp);
628 	int width, height;
629 	int i;
630 
631 	if (fival->index > 4)
632 		return -EINVAL;
633 
634 	if (!valid_pixelformat(fival->pixel_format))
635 		return -EINVAL;
636 
637 	if (!(go->board_info->sensor_flags & GO7007_SENSOR_SCALING)) {
638 		get_resolution(go, &width, &height);
639 		for (i = 0; i <= 2; i++)
640 			if (fival->width == ((width >> i) & ~0xf) &&
641 			    fival->height == ((height >> i) & ~0xf))
642 				break;
643 		if (i > 2)
644 			return -EINVAL;
645 	}
646 	fival->type = V4L2_FRMIVAL_TYPE_DISCRETE;
647 	fival->discrete.numerator = 1001 * (fival->index + 1);
648 	fival->discrete.denominator = go->sensor_framerate;
649 	return 0;
650 }
651 
vidioc_g_std(struct file * file,void * priv,v4l2_std_id * std)652 static int vidioc_g_std(struct file *file, void *priv, v4l2_std_id *std)
653 {
654 	struct go7007 *go = video_drvdata(file);
655 
656 	*std = go->std;
657 	return 0;
658 }
659 
go7007_s_std(struct go7007 * go)660 static int go7007_s_std(struct go7007 *go)
661 {
662 	if (go->std & V4L2_STD_625_50) {
663 		go->standard = GO7007_STD_PAL;
664 		go->sensor_framerate = 25025;
665 	} else {
666 		go->standard = GO7007_STD_NTSC;
667 		go->sensor_framerate = 30000;
668 	}
669 
670 	call_all(&go->v4l2_dev, core, s_std, go->std);
671 	set_capture_size(go, NULL, 0);
672 	return 0;
673 }
674 
vidioc_s_std(struct file * file,void * priv,v4l2_std_id std)675 static int vidioc_s_std(struct file *file, void *priv, v4l2_std_id std)
676 {
677 	struct go7007 *go = video_drvdata(file);
678 
679 	if (vb2_is_busy(&go->vidq))
680 		return -EBUSY;
681 
682 	go->std = std;
683 
684 	return go7007_s_std(go);
685 }
686 
vidioc_querystd(struct file * file,void * priv,v4l2_std_id * std)687 static int vidioc_querystd(struct file *file, void *priv, v4l2_std_id *std)
688 {
689 	struct go7007 *go = video_drvdata(file);
690 
691 	return call_all(&go->v4l2_dev, video, querystd, std);
692 }
693 
vidioc_enum_input(struct file * file,void * priv,struct v4l2_input * inp)694 static int vidioc_enum_input(struct file *file, void *priv,
695 				struct v4l2_input *inp)
696 {
697 	struct go7007 *go = video_drvdata(file);
698 
699 	if (inp->index >= go->board_info->num_inputs)
700 		return -EINVAL;
701 
702 	strncpy(inp->name, go->board_info->inputs[inp->index].name,
703 			sizeof(inp->name));
704 
705 	/* If this board has a tuner, it will be the first input */
706 	if ((go->board_info->flags & GO7007_BOARD_HAS_TUNER) &&
707 			inp->index == 0)
708 		inp->type = V4L2_INPUT_TYPE_TUNER;
709 	else
710 		inp->type = V4L2_INPUT_TYPE_CAMERA;
711 
712 	if (go->board_info->num_aud_inputs)
713 		inp->audioset = (1 << go->board_info->num_aud_inputs) - 1;
714 	else
715 		inp->audioset = 0;
716 	inp->tuner = 0;
717 	if (go->board_info->sensor_flags & GO7007_SENSOR_TV)
718 		inp->std = video_devdata(file)->tvnorms;
719 	else
720 		inp->std = 0;
721 
722 	return 0;
723 }
724 
725 
vidioc_g_input(struct file * file,void * priv,unsigned int * input)726 static int vidioc_g_input(struct file *file, void *priv, unsigned int *input)
727 {
728 	struct go7007 *go = video_drvdata(file);
729 
730 	*input = go->input;
731 
732 	return 0;
733 }
734 
vidioc_enumaudio(struct file * file,void * fh,struct v4l2_audio * a)735 static int vidioc_enumaudio(struct file *file, void *fh, struct v4l2_audio *a)
736 {
737 	struct go7007 *go = video_drvdata(file);
738 
739 	if (a->index >= go->board_info->num_aud_inputs)
740 		return -EINVAL;
741 	strlcpy(a->name, go->board_info->aud_inputs[a->index].name, sizeof(a->name));
742 	a->capability = V4L2_AUDCAP_STEREO;
743 	return 0;
744 }
745 
vidioc_g_audio(struct file * file,void * fh,struct v4l2_audio * a)746 static int vidioc_g_audio(struct file *file, void *fh, struct v4l2_audio *a)
747 {
748 	struct go7007 *go = video_drvdata(file);
749 
750 	a->index = go->aud_input;
751 	strlcpy(a->name, go->board_info->aud_inputs[go->aud_input].name, sizeof(a->name));
752 	a->capability = V4L2_AUDCAP_STEREO;
753 	return 0;
754 }
755 
vidioc_s_audio(struct file * file,void * fh,const struct v4l2_audio * a)756 static int vidioc_s_audio(struct file *file, void *fh, const struct v4l2_audio *a)
757 {
758 	struct go7007 *go = video_drvdata(file);
759 
760 	if (a->index >= go->board_info->num_aud_inputs)
761 		return -EINVAL;
762 	go->aud_input = a->index;
763 	v4l2_subdev_call(go->sd_audio, audio, s_routing,
764 			go->board_info->aud_inputs[go->aud_input].audio_input, 0, 0);
765 	return 0;
766 }
767 
go7007_s_input(struct go7007 * go)768 static void go7007_s_input(struct go7007 *go)
769 {
770 	unsigned int input = go->input;
771 
772 	v4l2_subdev_call(go->sd_video, video, s_routing,
773 			go->board_info->inputs[input].video_input, 0,
774 			go->board_info->video_config);
775 	if (go->board_info->num_aud_inputs) {
776 		int aud_input = go->board_info->inputs[input].audio_index;
777 
778 		v4l2_subdev_call(go->sd_audio, audio, s_routing,
779 			go->board_info->aud_inputs[aud_input].audio_input, 0, 0);
780 		go->aud_input = aud_input;
781 	}
782 }
783 
vidioc_s_input(struct file * file,void * priv,unsigned int input)784 static int vidioc_s_input(struct file *file, void *priv, unsigned int input)
785 {
786 	struct go7007 *go = video_drvdata(file);
787 
788 	if (input >= go->board_info->num_inputs)
789 		return -EINVAL;
790 	if (vb2_is_busy(&go->vidq))
791 		return -EBUSY;
792 
793 	go->input = input;
794 	go7007_s_input(go);
795 
796 	return 0;
797 }
798 
vidioc_g_tuner(struct file * file,void * priv,struct v4l2_tuner * t)799 static int vidioc_g_tuner(struct file *file, void *priv,
800 				struct v4l2_tuner *t)
801 {
802 	struct go7007 *go = video_drvdata(file);
803 
804 	if (t->index != 0)
805 		return -EINVAL;
806 
807 	strlcpy(t->name, "Tuner", sizeof(t->name));
808 	return call_all(&go->v4l2_dev, tuner, g_tuner, t);
809 }
810 
vidioc_s_tuner(struct file * file,void * priv,const struct v4l2_tuner * t)811 static int vidioc_s_tuner(struct file *file, void *priv,
812 				const struct v4l2_tuner *t)
813 {
814 	struct go7007 *go = video_drvdata(file);
815 
816 	if (t->index != 0)
817 		return -EINVAL;
818 
819 	return call_all(&go->v4l2_dev, tuner, s_tuner, t);
820 }
821 
vidioc_g_frequency(struct file * file,void * priv,struct v4l2_frequency * f)822 static int vidioc_g_frequency(struct file *file, void *priv,
823 				struct v4l2_frequency *f)
824 {
825 	struct go7007 *go = video_drvdata(file);
826 
827 	if (f->tuner)
828 		return -EINVAL;
829 
830 	return call_all(&go->v4l2_dev, tuner, g_frequency, f);
831 }
832 
vidioc_s_frequency(struct file * file,void * priv,const struct v4l2_frequency * f)833 static int vidioc_s_frequency(struct file *file, void *priv,
834 				const struct v4l2_frequency *f)
835 {
836 	struct go7007 *go = video_drvdata(file);
837 
838 	if (f->tuner)
839 		return -EINVAL;
840 
841 	return call_all(&go->v4l2_dev, tuner, s_frequency, f);
842 }
843 
vidioc_log_status(struct file * file,void * priv)844 static int vidioc_log_status(struct file *file, void *priv)
845 {
846 	struct go7007 *go = video_drvdata(file);
847 
848 	v4l2_ctrl_log_status(file, priv);
849 	return call_all(&go->v4l2_dev, core, log_status);
850 }
851 
852 /* FIXME:
853 	Those ioctls are private, and not needed, since several standard
854 	extended controls already provide streaming control.
855 	So, those ioctls should be converted into vidioc_g_ext_ctrls()
856 	and vidioc_s_ext_ctrls()
857  */
858 
859 #if 0
860 	case GO7007IOC_S_MD_PARAMS:
861 	{
862 		struct go7007_md_params *mdp = arg;
863 
864 		if (mdp->region > 3)
865 			return -EINVAL;
866 		if (mdp->trigger > 0) {
867 			go->modet[mdp->region].pixel_threshold =
868 					mdp->pixel_threshold >> 1;
869 			go->modet[mdp->region].motion_threshold =
870 					mdp->motion_threshold >> 1;
871 			go->modet[mdp->region].mb_threshold =
872 					mdp->trigger >> 1;
873 			go->modet[mdp->region].enable = 1;
874 		} else
875 			go->modet[mdp->region].enable = 0;
876 		/* fall-through */
877 	}
878 	case GO7007IOC_S_MD_REGION:
879 	{
880 		struct go7007_md_region *region = arg;
881 
882 		if (region->region < 1 || region->region > 3)
883 			return -EINVAL;
884 		return clip_to_modet_map(go, region->region, region->clips);
885 	}
886 #endif
887 
888 static struct v4l2_file_operations go7007_fops = {
889 	.owner		= THIS_MODULE,
890 	.open		= v4l2_fh_open,
891 	.release	= vb2_fop_release,
892 	.unlocked_ioctl	= video_ioctl2,
893 	.read		= vb2_fop_read,
894 	.mmap		= vb2_fop_mmap,
895 	.poll		= vb2_fop_poll,
896 };
897 
898 static const struct v4l2_ioctl_ops video_ioctl_ops = {
899 	.vidioc_querycap          = vidioc_querycap,
900 	.vidioc_enum_fmt_vid_cap  = vidioc_enum_fmt_vid_cap,
901 	.vidioc_g_fmt_vid_cap     = vidioc_g_fmt_vid_cap,
902 	.vidioc_try_fmt_vid_cap   = vidioc_try_fmt_vid_cap,
903 	.vidioc_s_fmt_vid_cap     = vidioc_s_fmt_vid_cap,
904 	.vidioc_reqbufs           = vb2_ioctl_reqbufs,
905 	.vidioc_querybuf          = vb2_ioctl_querybuf,
906 	.vidioc_qbuf              = vb2_ioctl_qbuf,
907 	.vidioc_dqbuf             = vb2_ioctl_dqbuf,
908 	.vidioc_g_std             = vidioc_g_std,
909 	.vidioc_s_std             = vidioc_s_std,
910 	.vidioc_querystd          = vidioc_querystd,
911 	.vidioc_enum_input        = vidioc_enum_input,
912 	.vidioc_g_input           = vidioc_g_input,
913 	.vidioc_s_input           = vidioc_s_input,
914 	.vidioc_enumaudio         = vidioc_enumaudio,
915 	.vidioc_g_audio           = vidioc_g_audio,
916 	.vidioc_s_audio           = vidioc_s_audio,
917 	.vidioc_streamon          = vb2_ioctl_streamon,
918 	.vidioc_streamoff         = vb2_ioctl_streamoff,
919 	.vidioc_g_tuner           = vidioc_g_tuner,
920 	.vidioc_s_tuner           = vidioc_s_tuner,
921 	.vidioc_g_frequency       = vidioc_g_frequency,
922 	.vidioc_s_frequency       = vidioc_s_frequency,
923 	.vidioc_g_parm            = vidioc_g_parm,
924 	.vidioc_s_parm            = vidioc_s_parm,
925 	.vidioc_enum_framesizes   = vidioc_enum_framesizes,
926 	.vidioc_enum_frameintervals = vidioc_enum_frameintervals,
927 	.vidioc_log_status        = vidioc_log_status,
928 	.vidioc_subscribe_event   = v4l2_ctrl_subscribe_event,
929 	.vidioc_unsubscribe_event = v4l2_event_unsubscribe,
930 };
931 
932 static struct video_device go7007_template = {
933 	.name		= "go7007",
934 	.fops		= &go7007_fops,
935 	.release	= video_device_release_empty,
936 	.ioctl_ops	= &video_ioctl_ops,
937 	.tvnorms	= V4L2_STD_ALL,
938 };
939 
go7007_v4l2_ctrl_init(struct go7007 * go)940 int go7007_v4l2_ctrl_init(struct go7007 *go)
941 {
942 	struct v4l2_ctrl_handler *hdl = &go->hdl;
943 	struct v4l2_ctrl *ctrl;
944 
945 	v4l2_ctrl_handler_init(hdl, 13);
946 	go->mpeg_video_gop_size = v4l2_ctrl_new_std(hdl, NULL,
947 			V4L2_CID_MPEG_VIDEO_GOP_SIZE, 0, 34, 1, 15);
948 	go->mpeg_video_gop_closure = v4l2_ctrl_new_std(hdl, NULL,
949 			V4L2_CID_MPEG_VIDEO_GOP_CLOSURE, 0, 1, 1, 1);
950 	go->mpeg_video_bitrate = v4l2_ctrl_new_std(hdl, NULL,
951 			V4L2_CID_MPEG_VIDEO_BITRATE,
952 			64000, 10000000, 1, 9800000);
953 	go->mpeg_video_b_frames = v4l2_ctrl_new_std(hdl, NULL,
954 			V4L2_CID_MPEG_VIDEO_B_FRAMES, 0, 2, 2, 0);
955 	go->mpeg_video_rep_seqheader = v4l2_ctrl_new_std(hdl, NULL,
956 			V4L2_CID_MPEG_VIDEO_REPEAT_SEQ_HEADER, 0, 1, 1, 1);
957 
958 	go->mpeg_video_aspect_ratio = v4l2_ctrl_new_std_menu(hdl, NULL,
959 			V4L2_CID_MPEG_VIDEO_ASPECT,
960 			V4L2_MPEG_VIDEO_ASPECT_16x9, 0,
961 			V4L2_MPEG_VIDEO_ASPECT_1x1);
962 	ctrl = v4l2_ctrl_new_std(hdl, NULL,
963 			V4L2_CID_JPEG_ACTIVE_MARKER, 0,
964 			V4L2_JPEG_ACTIVE_MARKER_DQT | V4L2_JPEG_ACTIVE_MARKER_DHT, 0,
965 			V4L2_JPEG_ACTIVE_MARKER_DQT | V4L2_JPEG_ACTIVE_MARKER_DHT);
966 	if (ctrl)
967 		ctrl->flags |= V4L2_CTRL_FLAG_READ_ONLY;
968 	if (hdl->error) {
969 		int rv = hdl->error;
970 
971 		v4l2_err(&go->v4l2_dev, "Could not register controls\n");
972 		return rv;
973 	}
974 	go->v4l2_dev.ctrl_handler = hdl;
975 	return 0;
976 }
977 
go7007_v4l2_init(struct go7007 * go)978 int go7007_v4l2_init(struct go7007 *go)
979 {
980 	struct video_device *vdev = &go->vdev;
981 	int rv;
982 
983 	mutex_init(&go->serialize_lock);
984 	mutex_init(&go->queue_lock);
985 
986 	INIT_LIST_HEAD(&go->vidq_active);
987 	go->vidq.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
988 	go->vidq.io_modes = VB2_MMAP | VB2_USERPTR | VB2_READ;
989 	go->vidq.ops = &go7007_video_qops;
990 	go->vidq.mem_ops = &vb2_vmalloc_memops;
991 	go->vidq.drv_priv = go;
992 	go->vidq.buf_struct_size = sizeof(struct go7007_buffer);
993 	go->vidq.timestamp_type = V4L2_BUF_FLAG_TIMESTAMP_MONOTONIC;
994 	go->vidq.lock = &go->queue_lock;
995 	rv = vb2_queue_init(&go->vidq);
996 	if (rv)
997 		return rv;
998 	*vdev = go7007_template;
999 	vdev->lock = &go->serialize_lock;
1000 	vdev->queue = &go->vidq;
1001 	set_bit(V4L2_FL_USE_FH_PRIO, &vdev->flags);
1002 	video_set_drvdata(vdev, go);
1003 	vdev->v4l2_dev = &go->v4l2_dev;
1004 	if (!v4l2_device_has_op(&go->v4l2_dev, video, querystd))
1005 		v4l2_disable_ioctl(vdev, VIDIOC_QUERYSTD);
1006 	if (!(go->board_info->flags & GO7007_BOARD_HAS_TUNER)) {
1007 		v4l2_disable_ioctl(vdev, VIDIOC_S_FREQUENCY);
1008 		v4l2_disable_ioctl(vdev, VIDIOC_G_FREQUENCY);
1009 		v4l2_disable_ioctl(vdev, VIDIOC_S_TUNER);
1010 		v4l2_disable_ioctl(vdev, VIDIOC_G_TUNER);
1011 	} else {
1012 		struct v4l2_frequency f = {
1013 			.type = V4L2_TUNER_ANALOG_TV,
1014 			.frequency = 980,
1015 		};
1016 
1017 		call_all(&go->v4l2_dev, tuner, s_frequency, &f);
1018 	}
1019 	if (!(go->board_info->sensor_flags & GO7007_SENSOR_TV)) {
1020 		v4l2_disable_ioctl(vdev, VIDIOC_G_STD);
1021 		v4l2_disable_ioctl(vdev, VIDIOC_S_STD);
1022 		vdev->tvnorms = 0;
1023 	}
1024 	if (go->board_info->sensor_flags & GO7007_SENSOR_SCALING)
1025 		v4l2_disable_ioctl(vdev, VIDIOC_ENUM_FRAMESIZES);
1026 	if (go->board_info->num_aud_inputs == 0) {
1027 		v4l2_disable_ioctl(vdev, VIDIOC_G_AUDIO);
1028 		v4l2_disable_ioctl(vdev, VIDIOC_S_AUDIO);
1029 		v4l2_disable_ioctl(vdev, VIDIOC_ENUMAUDIO);
1030 	}
1031 	/* Setup correct crystal frequency on this board */
1032 	if (go->board_info->sensor_flags & GO7007_SENSOR_SAA7115)
1033 		v4l2_subdev_call(go->sd_video, video, s_crystal_freq,
1034 				SAA7115_FREQ_24_576_MHZ,
1035 				SAA7115_FREQ_FL_APLL | SAA7115_FREQ_FL_UCGC |
1036 				SAA7115_FREQ_FL_DOUBLE_ASCLK);
1037 	go7007_s_input(go);
1038 	if (go->board_info->sensor_flags & GO7007_SENSOR_TV)
1039 		go7007_s_std(go);
1040 	rv = video_register_device(vdev, VFL_TYPE_GRABBER, -1);
1041 	if (rv < 0)
1042 		return rv;
1043 	dev_info(go->dev, "registered device %s [v4l2]\n",
1044 		 video_device_node_name(vdev));
1045 
1046 	return 0;
1047 }
1048 
go7007_v4l2_remove(struct go7007 * go)1049 void go7007_v4l2_remove(struct go7007 *go)
1050 {
1051 	v4l2_ctrl_handler_free(&go->hdl);
1052 }
1053