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