xref: /linux/drivers/media/usb/go7007/go7007-v4l2.c (revision c532de5a67a70f8533d495f8f2aaa9a0491c3ad0)
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 	if (go7007_start_encoder(go) < 0)
408 		ret = -EIO;
409 	else
410 		ret = 0;
411 	mutex_unlock(&go->hw_lock);
412 	if (ret)
413 		return ret;
414 	call_all(&go->v4l2_dev, video, s_stream, 1);
415 	v4l2_ctrl_grab(go->mpeg_video_gop_size, true);
416 	v4l2_ctrl_grab(go->mpeg_video_gop_closure, true);
417 	v4l2_ctrl_grab(go->mpeg_video_bitrate, true);
418 	v4l2_ctrl_grab(go->mpeg_video_aspect_ratio, true);
419 	/* Turn on Capture LED */
420 	if (go->board_id == GO7007_BOARDID_ADS_USBAV_709)
421 		go7007_write_addr(go, 0x3c82, 0x0005);
422 	return ret;
423 }
424 
425 static void go7007_stop_streaming(struct vb2_queue *q)
426 {
427 	struct go7007 *go = vb2_get_drv_priv(q);
428 	unsigned long flags;
429 
430 	go7007_stream_stop(go);
431 	mutex_lock(&go->hw_lock);
432 	go7007_reset_encoder(go);
433 	mutex_unlock(&go->hw_lock);
434 	call_all(&go->v4l2_dev, video, s_stream, 0);
435 
436 	spin_lock_irqsave(&go->spinlock, flags);
437 	INIT_LIST_HEAD(&go->vidq_active);
438 	spin_unlock_irqrestore(&go->spinlock, flags);
439 	v4l2_ctrl_grab(go->mpeg_video_gop_size, false);
440 	v4l2_ctrl_grab(go->mpeg_video_gop_closure, false);
441 	v4l2_ctrl_grab(go->mpeg_video_bitrate, false);
442 	v4l2_ctrl_grab(go->mpeg_video_aspect_ratio, false);
443 	/* Turn on Capture LED */
444 	if (go->board_id == GO7007_BOARDID_ADS_USBAV_709)
445 		go7007_write_addr(go, 0x3c82, 0x000d);
446 }
447 
448 static const struct vb2_ops go7007_video_qops = {
449 	.queue_setup    = go7007_queue_setup,
450 	.buf_queue      = go7007_buf_queue,
451 	.buf_prepare    = go7007_buf_prepare,
452 	.buf_finish     = go7007_buf_finish,
453 	.start_streaming = go7007_start_streaming,
454 	.stop_streaming = go7007_stop_streaming,
455 	.wait_prepare   = vb2_ops_wait_prepare,
456 	.wait_finish    = vb2_ops_wait_finish,
457 };
458 
459 static int vidioc_g_parm(struct file *filp, void *priv,
460 		struct v4l2_streamparm *parm)
461 {
462 	struct go7007 *go = video_drvdata(filp);
463 	struct v4l2_fract timeperframe = {
464 		.numerator = 1001 *  go->fps_scale,
465 		.denominator = go->sensor_framerate,
466 	};
467 
468 	if (parm->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
469 		return -EINVAL;
470 
471 	parm->parm.capture.readbuffers = 2;
472 	parm->parm.capture.capability = V4L2_CAP_TIMEPERFRAME;
473 	parm->parm.capture.timeperframe = timeperframe;
474 
475 	return 0;
476 }
477 
478 static int vidioc_s_parm(struct file *filp, void *priv,
479 		struct v4l2_streamparm *parm)
480 {
481 	struct go7007 *go = video_drvdata(filp);
482 	unsigned int n, d;
483 
484 	if (parm->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
485 		return -EINVAL;
486 
487 	n = go->sensor_framerate *
488 		parm->parm.capture.timeperframe.numerator;
489 	d = 1001 * parm->parm.capture.timeperframe.denominator;
490 	if (n != 0 && d != 0 && n > d)
491 		go->fps_scale = (n + d/2) / d;
492 	else
493 		go->fps_scale = 1;
494 
495 	return vidioc_g_parm(filp, priv, parm);
496 }
497 
498 /* VIDIOC_ENUMSTD on go7007 were used for enumerating the supported fps and
499    its resolution, when the device is not connected to TV.
500    This is were an API abuse, probably used by the lack of specific IOCTL's to
501    enumerate it, by the time the driver was written.
502 
503    However, since kernel 2.6.19, two new ioctls (VIDIOC_ENUM_FRAMEINTERVALS
504    and VIDIOC_ENUM_FRAMESIZES) were added for this purpose.
505 
506    The two functions below implement the newer ioctls
507 */
508 static int vidioc_enum_framesizes(struct file *filp, void *priv,
509 				  struct v4l2_frmsizeenum *fsize)
510 {
511 	struct go7007 *go = video_drvdata(filp);
512 	int width, height;
513 
514 	if (fsize->index > 2)
515 		return -EINVAL;
516 
517 	if (!valid_pixelformat(fsize->pixel_format))
518 		return -EINVAL;
519 
520 	get_resolution(go, &width, &height);
521 	fsize->type = V4L2_FRMSIZE_TYPE_DISCRETE;
522 	fsize->discrete.width = (width >> fsize->index) & ~0xf;
523 	fsize->discrete.height = (height >> fsize->index) & ~0xf;
524 	return 0;
525 }
526 
527 static int vidioc_enum_frameintervals(struct file *filp, void *priv,
528 				      struct v4l2_frmivalenum *fival)
529 {
530 	struct go7007 *go = video_drvdata(filp);
531 	int width, height;
532 	int i;
533 
534 	if (fival->index > 4)
535 		return -EINVAL;
536 
537 	if (!valid_pixelformat(fival->pixel_format))
538 		return -EINVAL;
539 
540 	if (!(go->board_info->sensor_flags & GO7007_SENSOR_SCALING)) {
541 		get_resolution(go, &width, &height);
542 		for (i = 0; i <= 2; i++)
543 			if (fival->width == ((width >> i) & ~0xf) &&
544 			    fival->height == ((height >> i) & ~0xf))
545 				break;
546 		if (i > 2)
547 			return -EINVAL;
548 	}
549 	fival->type = V4L2_FRMIVAL_TYPE_DISCRETE;
550 	fival->discrete.numerator = 1001 * (fival->index + 1);
551 	fival->discrete.denominator = go->sensor_framerate;
552 	return 0;
553 }
554 
555 static int vidioc_g_std(struct file *file, void *priv, v4l2_std_id *std)
556 {
557 	struct go7007 *go = video_drvdata(file);
558 
559 	*std = go->std;
560 	return 0;
561 }
562 
563 static int go7007_s_std(struct go7007 *go)
564 {
565 	if (go->std & V4L2_STD_625_50) {
566 		go->standard = GO7007_STD_PAL;
567 		go->sensor_framerate = 25025;
568 	} else {
569 		go->standard = GO7007_STD_NTSC;
570 		go->sensor_framerate = 30000;
571 	}
572 
573 	call_all(&go->v4l2_dev, video, s_std, go->std);
574 	set_capture_size(go, NULL, 0);
575 	return 0;
576 }
577 
578 static int vidioc_s_std(struct file *file, void *priv, v4l2_std_id std)
579 {
580 	struct go7007 *go = video_drvdata(file);
581 
582 	if (vb2_is_busy(&go->vidq))
583 		return -EBUSY;
584 
585 	go->std = std;
586 
587 	return go7007_s_std(go);
588 }
589 
590 static int vidioc_querystd(struct file *file, void *priv, v4l2_std_id *std)
591 {
592 	struct go7007 *go = video_drvdata(file);
593 
594 	return call_all(&go->v4l2_dev, video, querystd, std);
595 }
596 
597 static int vidioc_enum_input(struct file *file, void *priv,
598 				struct v4l2_input *inp)
599 {
600 	struct go7007 *go = video_drvdata(file);
601 
602 	if (inp->index >= go->board_info->num_inputs)
603 		return -EINVAL;
604 
605 	strscpy(inp->name, go->board_info->inputs[inp->index].name,
606 		sizeof(inp->name));
607 
608 	/* If this board has a tuner, it will be the first input */
609 	if ((go->board_info->flags & GO7007_BOARD_HAS_TUNER) &&
610 			inp->index == 0)
611 		inp->type = V4L2_INPUT_TYPE_TUNER;
612 	else
613 		inp->type = V4L2_INPUT_TYPE_CAMERA;
614 
615 	if (go->board_info->num_aud_inputs)
616 		inp->audioset = (1 << go->board_info->num_aud_inputs) - 1;
617 	else
618 		inp->audioset = 0;
619 	inp->tuner = 0;
620 	if (go->board_info->sensor_flags & GO7007_SENSOR_TV)
621 		inp->std = video_devdata(file)->tvnorms;
622 	else
623 		inp->std = 0;
624 
625 	return 0;
626 }
627 
628 
629 static int vidioc_g_input(struct file *file, void *priv, unsigned int *input)
630 {
631 	struct go7007 *go = video_drvdata(file);
632 
633 	*input = go->input;
634 
635 	return 0;
636 }
637 
638 static int vidioc_enumaudio(struct file *file, void *fh, struct v4l2_audio *a)
639 {
640 	struct go7007 *go = video_drvdata(file);
641 
642 	if (a->index >= go->board_info->num_aud_inputs)
643 		return -EINVAL;
644 	strscpy(a->name, go->board_info->aud_inputs[a->index].name,
645 		sizeof(a->name));
646 	a->capability = V4L2_AUDCAP_STEREO;
647 	return 0;
648 }
649 
650 static int vidioc_g_audio(struct file *file, void *fh, struct v4l2_audio *a)
651 {
652 	struct go7007 *go = video_drvdata(file);
653 
654 	a->index = go->aud_input;
655 	strscpy(a->name, go->board_info->aud_inputs[go->aud_input].name,
656 		sizeof(a->name));
657 	a->capability = V4L2_AUDCAP_STEREO;
658 	return 0;
659 }
660 
661 static int vidioc_s_audio(struct file *file, void *fh,
662 	const struct v4l2_audio *a)
663 {
664 	struct go7007 *go = video_drvdata(file);
665 
666 	if (a->index >= go->board_info->num_aud_inputs)
667 		return -EINVAL;
668 	go->aud_input = a->index;
669 	v4l2_subdev_call(go->sd_audio, audio, s_routing,
670 		go->board_info->aud_inputs[go->aud_input].audio_input, 0, 0);
671 	return 0;
672 }
673 
674 static void go7007_s_input(struct go7007 *go)
675 {
676 	unsigned int input = go->input;
677 
678 	v4l2_subdev_call(go->sd_video, video, s_routing,
679 			go->board_info->inputs[input].video_input, 0,
680 			go->board_info->video_config);
681 	if (go->board_info->num_aud_inputs) {
682 		int aud_input = go->board_info->inputs[input].audio_index;
683 
684 		v4l2_subdev_call(go->sd_audio, audio, s_routing,
685 			go->board_info->aud_inputs[aud_input].audio_input, 0, 0);
686 		go->aud_input = aud_input;
687 	}
688 }
689 
690 static int vidioc_s_input(struct file *file, void *priv, unsigned int input)
691 {
692 	struct go7007 *go = video_drvdata(file);
693 
694 	if (input >= go->board_info->num_inputs)
695 		return -EINVAL;
696 	if (vb2_is_busy(&go->vidq))
697 		return -EBUSY;
698 
699 	go->input = input;
700 	go7007_s_input(go);
701 
702 	return 0;
703 }
704 
705 static int vidioc_g_tuner(struct file *file, void *priv,
706 				struct v4l2_tuner *t)
707 {
708 	struct go7007 *go = video_drvdata(file);
709 
710 	if (t->index != 0)
711 		return -EINVAL;
712 
713 	strscpy(t->name, "Tuner", sizeof(t->name));
714 	return call_all(&go->v4l2_dev, tuner, g_tuner, t);
715 }
716 
717 static int vidioc_s_tuner(struct file *file, void *priv,
718 				const struct v4l2_tuner *t)
719 {
720 	struct go7007 *go = video_drvdata(file);
721 
722 	if (t->index != 0)
723 		return -EINVAL;
724 
725 	return call_all(&go->v4l2_dev, tuner, s_tuner, t);
726 }
727 
728 static int vidioc_g_frequency(struct file *file, void *priv,
729 				struct v4l2_frequency *f)
730 {
731 	struct go7007 *go = video_drvdata(file);
732 
733 	if (f->tuner)
734 		return -EINVAL;
735 
736 	return call_all(&go->v4l2_dev, tuner, g_frequency, f);
737 }
738 
739 static int vidioc_s_frequency(struct file *file, void *priv,
740 				const struct v4l2_frequency *f)
741 {
742 	struct go7007 *go = video_drvdata(file);
743 
744 	if (f->tuner)
745 		return -EINVAL;
746 
747 	return call_all(&go->v4l2_dev, tuner, s_frequency, f);
748 }
749 
750 static int vidioc_log_status(struct file *file, void *priv)
751 {
752 	struct go7007 *go = video_drvdata(file);
753 
754 	v4l2_ctrl_log_status(file, priv);
755 	return call_all(&go->v4l2_dev, core, log_status);
756 }
757 
758 static int vidioc_subscribe_event(struct v4l2_fh *fh,
759 				const struct v4l2_event_subscription *sub)
760 {
761 
762 	switch (sub->type) {
763 	case V4L2_EVENT_MOTION_DET:
764 		/* Allow for up to 30 events (1 second for NTSC) to be
765 		 * stored. */
766 		return v4l2_event_subscribe(fh, sub, 30, NULL);
767 	default:
768 		return v4l2_ctrl_subscribe_event(fh, sub);
769 	}
770 }
771 
772 
773 static int go7007_s_ctrl(struct v4l2_ctrl *ctrl)
774 {
775 	struct go7007 *go =
776 		container_of(ctrl->handler, struct go7007, hdl);
777 	unsigned y;
778 	u8 *mt;
779 
780 	switch (ctrl->id) {
781 	case V4L2_CID_PIXEL_THRESHOLD0:
782 		go->modet[0].pixel_threshold = ctrl->val;
783 		break;
784 	case V4L2_CID_MOTION_THRESHOLD0:
785 		go->modet[0].motion_threshold = ctrl->val;
786 		break;
787 	case V4L2_CID_MB_THRESHOLD0:
788 		go->modet[0].mb_threshold = ctrl->val;
789 		break;
790 	case V4L2_CID_PIXEL_THRESHOLD1:
791 		go->modet[1].pixel_threshold = ctrl->val;
792 		break;
793 	case V4L2_CID_MOTION_THRESHOLD1:
794 		go->modet[1].motion_threshold = ctrl->val;
795 		break;
796 	case V4L2_CID_MB_THRESHOLD1:
797 		go->modet[1].mb_threshold = ctrl->val;
798 		break;
799 	case V4L2_CID_PIXEL_THRESHOLD2:
800 		go->modet[2].pixel_threshold = ctrl->val;
801 		break;
802 	case V4L2_CID_MOTION_THRESHOLD2:
803 		go->modet[2].motion_threshold = ctrl->val;
804 		break;
805 	case V4L2_CID_MB_THRESHOLD2:
806 		go->modet[2].mb_threshold = ctrl->val;
807 		break;
808 	case V4L2_CID_PIXEL_THRESHOLD3:
809 		go->modet[3].pixel_threshold = ctrl->val;
810 		break;
811 	case V4L2_CID_MOTION_THRESHOLD3:
812 		go->modet[3].motion_threshold = ctrl->val;
813 		break;
814 	case V4L2_CID_MB_THRESHOLD3:
815 		go->modet[3].mb_threshold = ctrl->val;
816 		break;
817 	case V4L2_CID_DETECT_MD_REGION_GRID:
818 		mt = go->modet_map;
819 		for (y = 0; y < go->height / 16; y++, mt += go->width / 16)
820 			memcpy(mt, ctrl->p_new.p_u8 + y * (720 / 16), go->width / 16);
821 		break;
822 	default:
823 		return -EINVAL;
824 	}
825 	return 0;
826 }
827 
828 static const struct v4l2_file_operations go7007_fops = {
829 	.owner		= THIS_MODULE,
830 	.open		= v4l2_fh_open,
831 	.release	= vb2_fop_release,
832 	.unlocked_ioctl	= video_ioctl2,
833 	.read		= vb2_fop_read,
834 	.mmap		= vb2_fop_mmap,
835 	.poll		= vb2_fop_poll,
836 };
837 
838 static const struct v4l2_ioctl_ops video_ioctl_ops = {
839 	.vidioc_querycap          = vidioc_querycap,
840 	.vidioc_enum_fmt_vid_cap  = vidioc_enum_fmt_vid_cap,
841 	.vidioc_g_fmt_vid_cap     = vidioc_g_fmt_vid_cap,
842 	.vidioc_try_fmt_vid_cap   = vidioc_try_fmt_vid_cap,
843 	.vidioc_s_fmt_vid_cap     = vidioc_s_fmt_vid_cap,
844 	.vidioc_reqbufs           = vb2_ioctl_reqbufs,
845 	.vidioc_querybuf          = vb2_ioctl_querybuf,
846 	.vidioc_qbuf              = vb2_ioctl_qbuf,
847 	.vidioc_dqbuf             = vb2_ioctl_dqbuf,
848 	.vidioc_g_std             = vidioc_g_std,
849 	.vidioc_s_std             = vidioc_s_std,
850 	.vidioc_querystd          = vidioc_querystd,
851 	.vidioc_enum_input        = vidioc_enum_input,
852 	.vidioc_g_input           = vidioc_g_input,
853 	.vidioc_s_input           = vidioc_s_input,
854 	.vidioc_enumaudio         = vidioc_enumaudio,
855 	.vidioc_g_audio           = vidioc_g_audio,
856 	.vidioc_s_audio           = vidioc_s_audio,
857 	.vidioc_streamon          = vb2_ioctl_streamon,
858 	.vidioc_streamoff         = vb2_ioctl_streamoff,
859 	.vidioc_g_tuner           = vidioc_g_tuner,
860 	.vidioc_s_tuner           = vidioc_s_tuner,
861 	.vidioc_g_frequency       = vidioc_g_frequency,
862 	.vidioc_s_frequency       = vidioc_s_frequency,
863 	.vidioc_g_parm            = vidioc_g_parm,
864 	.vidioc_s_parm            = vidioc_s_parm,
865 	.vidioc_enum_framesizes   = vidioc_enum_framesizes,
866 	.vidioc_enum_frameintervals = vidioc_enum_frameintervals,
867 	.vidioc_log_status        = vidioc_log_status,
868 	.vidioc_subscribe_event   = vidioc_subscribe_event,
869 	.vidioc_unsubscribe_event = v4l2_event_unsubscribe,
870 };
871 
872 static const struct video_device go7007_template = {
873 	.name		= "go7007",
874 	.fops		= &go7007_fops,
875 	.release	= video_device_release_empty,
876 	.ioctl_ops	= &video_ioctl_ops,
877 	.tvnorms	= V4L2_STD_ALL,
878 };
879 
880 static const struct v4l2_ctrl_ops go7007_ctrl_ops = {
881 	.s_ctrl = go7007_s_ctrl,
882 };
883 
884 static const struct v4l2_ctrl_config go7007_pixel_threshold0_ctrl = {
885 	.ops = &go7007_ctrl_ops,
886 	.id = V4L2_CID_PIXEL_THRESHOLD0,
887 	.name = "Pixel Threshold Region 0",
888 	.type = V4L2_CTRL_TYPE_INTEGER,
889 	.def = 20,
890 	.max = 32767,
891 	.step = 1,
892 };
893 
894 static const struct v4l2_ctrl_config go7007_motion_threshold0_ctrl = {
895 	.ops = &go7007_ctrl_ops,
896 	.id = V4L2_CID_MOTION_THRESHOLD0,
897 	.name = "Motion Threshold Region 0",
898 	.type = V4L2_CTRL_TYPE_INTEGER,
899 	.def = 80,
900 	.max = 32767,
901 	.step = 1,
902 };
903 
904 static const struct v4l2_ctrl_config go7007_mb_threshold0_ctrl = {
905 	.ops = &go7007_ctrl_ops,
906 	.id = V4L2_CID_MB_THRESHOLD0,
907 	.name = "MB Threshold Region 0",
908 	.type = V4L2_CTRL_TYPE_INTEGER,
909 	.def = 200,
910 	.max = 32767,
911 	.step = 1,
912 };
913 
914 static const struct v4l2_ctrl_config go7007_pixel_threshold1_ctrl = {
915 	.ops = &go7007_ctrl_ops,
916 	.id = V4L2_CID_PIXEL_THRESHOLD1,
917 	.name = "Pixel Threshold Region 1",
918 	.type = V4L2_CTRL_TYPE_INTEGER,
919 	.def = 20,
920 	.max = 32767,
921 	.step = 1,
922 };
923 
924 static const struct v4l2_ctrl_config go7007_motion_threshold1_ctrl = {
925 	.ops = &go7007_ctrl_ops,
926 	.id = V4L2_CID_MOTION_THRESHOLD1,
927 	.name = "Motion Threshold Region 1",
928 	.type = V4L2_CTRL_TYPE_INTEGER,
929 	.def = 80,
930 	.max = 32767,
931 	.step = 1,
932 };
933 
934 static const struct v4l2_ctrl_config go7007_mb_threshold1_ctrl = {
935 	.ops = &go7007_ctrl_ops,
936 	.id = V4L2_CID_MB_THRESHOLD1,
937 	.name = "MB Threshold Region 1",
938 	.type = V4L2_CTRL_TYPE_INTEGER,
939 	.def = 200,
940 	.max = 32767,
941 	.step = 1,
942 };
943 
944 static const struct v4l2_ctrl_config go7007_pixel_threshold2_ctrl = {
945 	.ops = &go7007_ctrl_ops,
946 	.id = V4L2_CID_PIXEL_THRESHOLD2,
947 	.name = "Pixel Threshold Region 2",
948 	.type = V4L2_CTRL_TYPE_INTEGER,
949 	.def = 20,
950 	.max = 32767,
951 	.step = 1,
952 };
953 
954 static const struct v4l2_ctrl_config go7007_motion_threshold2_ctrl = {
955 	.ops = &go7007_ctrl_ops,
956 	.id = V4L2_CID_MOTION_THRESHOLD2,
957 	.name = "Motion Threshold Region 2",
958 	.type = V4L2_CTRL_TYPE_INTEGER,
959 	.def = 80,
960 	.max = 32767,
961 	.step = 1,
962 };
963 
964 static const struct v4l2_ctrl_config go7007_mb_threshold2_ctrl = {
965 	.ops = &go7007_ctrl_ops,
966 	.id = V4L2_CID_MB_THRESHOLD2,
967 	.name = "MB Threshold Region 2",
968 	.type = V4L2_CTRL_TYPE_INTEGER,
969 	.def = 200,
970 	.max = 32767,
971 	.step = 1,
972 };
973 
974 static const struct v4l2_ctrl_config go7007_pixel_threshold3_ctrl = {
975 	.ops = &go7007_ctrl_ops,
976 	.id = V4L2_CID_PIXEL_THRESHOLD3,
977 	.name = "Pixel Threshold Region 3",
978 	.type = V4L2_CTRL_TYPE_INTEGER,
979 	.def = 20,
980 	.max = 32767,
981 	.step = 1,
982 };
983 
984 static const struct v4l2_ctrl_config go7007_motion_threshold3_ctrl = {
985 	.ops = &go7007_ctrl_ops,
986 	.id = V4L2_CID_MOTION_THRESHOLD3,
987 	.name = "Motion Threshold Region 3",
988 	.type = V4L2_CTRL_TYPE_INTEGER,
989 	.def = 80,
990 	.max = 32767,
991 	.step = 1,
992 };
993 
994 static const struct v4l2_ctrl_config go7007_mb_threshold3_ctrl = {
995 	.ops = &go7007_ctrl_ops,
996 	.id = V4L2_CID_MB_THRESHOLD3,
997 	.name = "MB Threshold Region 3",
998 	.type = V4L2_CTRL_TYPE_INTEGER,
999 	.def = 200,
1000 	.max = 32767,
1001 	.step = 1,
1002 };
1003 
1004 static const struct v4l2_ctrl_config go7007_mb_regions_ctrl = {
1005 	.ops = &go7007_ctrl_ops,
1006 	.id = V4L2_CID_DETECT_MD_REGION_GRID,
1007 	.dims = { 576 / 16, 720 / 16 },
1008 	.max = 3,
1009 	.step = 1,
1010 };
1011 
1012 int go7007_v4l2_ctrl_init(struct go7007 *go)
1013 {
1014 	struct v4l2_ctrl_handler *hdl = &go->hdl;
1015 	struct v4l2_ctrl *ctrl;
1016 
1017 	v4l2_ctrl_handler_init(hdl, 22);
1018 	go->mpeg_video_gop_size = v4l2_ctrl_new_std(hdl, NULL,
1019 			V4L2_CID_MPEG_VIDEO_GOP_SIZE, 0, 34, 1, 15);
1020 	go->mpeg_video_gop_closure = v4l2_ctrl_new_std(hdl, NULL,
1021 			V4L2_CID_MPEG_VIDEO_GOP_CLOSURE, 0, 1, 1, 1);
1022 	go->mpeg_video_bitrate = v4l2_ctrl_new_std(hdl, NULL,
1023 			V4L2_CID_MPEG_VIDEO_BITRATE,
1024 			64000, 10000000, 1, 9800000);
1025 	go->mpeg_video_b_frames = v4l2_ctrl_new_std(hdl, NULL,
1026 			V4L2_CID_MPEG_VIDEO_B_FRAMES, 0, 2, 2, 0);
1027 	go->mpeg_video_rep_seqheader = v4l2_ctrl_new_std(hdl, NULL,
1028 			V4L2_CID_MPEG_VIDEO_REPEAT_SEQ_HEADER, 0, 1, 1, 1);
1029 
1030 	go->mpeg_video_aspect_ratio = v4l2_ctrl_new_std_menu(hdl, NULL,
1031 			V4L2_CID_MPEG_VIDEO_ASPECT,
1032 			V4L2_MPEG_VIDEO_ASPECT_16x9, 0,
1033 			V4L2_MPEG_VIDEO_ASPECT_1x1);
1034 	ctrl = v4l2_ctrl_new_std(hdl, NULL,
1035 			V4L2_CID_JPEG_ACTIVE_MARKER, 0,
1036 			V4L2_JPEG_ACTIVE_MARKER_DQT |
1037 			V4L2_JPEG_ACTIVE_MARKER_DHT, 0,
1038 			V4L2_JPEG_ACTIVE_MARKER_DQT |
1039 			V4L2_JPEG_ACTIVE_MARKER_DHT);
1040 	if (ctrl)
1041 		ctrl->flags |= V4L2_CTRL_FLAG_READ_ONLY;
1042 	v4l2_ctrl_new_custom(hdl, &go7007_pixel_threshold0_ctrl, NULL);
1043 	v4l2_ctrl_new_custom(hdl, &go7007_motion_threshold0_ctrl, NULL);
1044 	v4l2_ctrl_new_custom(hdl, &go7007_mb_threshold0_ctrl, NULL);
1045 	v4l2_ctrl_new_custom(hdl, &go7007_pixel_threshold1_ctrl, NULL);
1046 	v4l2_ctrl_new_custom(hdl, &go7007_motion_threshold1_ctrl, NULL);
1047 	v4l2_ctrl_new_custom(hdl, &go7007_mb_threshold1_ctrl, NULL);
1048 	v4l2_ctrl_new_custom(hdl, &go7007_pixel_threshold2_ctrl, NULL);
1049 	v4l2_ctrl_new_custom(hdl, &go7007_motion_threshold2_ctrl, NULL);
1050 	v4l2_ctrl_new_custom(hdl, &go7007_mb_threshold2_ctrl, NULL);
1051 	v4l2_ctrl_new_custom(hdl, &go7007_pixel_threshold3_ctrl, NULL);
1052 	v4l2_ctrl_new_custom(hdl, &go7007_motion_threshold3_ctrl, NULL);
1053 	v4l2_ctrl_new_custom(hdl, &go7007_mb_threshold3_ctrl, NULL);
1054 	v4l2_ctrl_new_custom(hdl, &go7007_mb_regions_ctrl, NULL);
1055 	go->modet_mode = v4l2_ctrl_new_std_menu(hdl, NULL,
1056 			V4L2_CID_DETECT_MD_MODE,
1057 			V4L2_DETECT_MD_MODE_REGION_GRID,
1058 			1 << V4L2_DETECT_MD_MODE_THRESHOLD_GRID,
1059 			V4L2_DETECT_MD_MODE_DISABLED);
1060 	if (hdl->error) {
1061 		int rv = hdl->error;
1062 
1063 		v4l2_err(&go->v4l2_dev, "Could not register controls\n");
1064 		return rv;
1065 	}
1066 	go->v4l2_dev.ctrl_handler = hdl;
1067 	return 0;
1068 }
1069 
1070 int go7007_v4l2_init(struct go7007 *go)
1071 {
1072 	struct video_device *vdev = &go->vdev;
1073 	int rv;
1074 
1075 	mutex_init(&go->serialize_lock);
1076 	mutex_init(&go->queue_lock);
1077 
1078 	INIT_LIST_HEAD(&go->vidq_active);
1079 	go->vidq.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
1080 	go->vidq.io_modes = VB2_MMAP | VB2_USERPTR | VB2_READ;
1081 	go->vidq.ops = &go7007_video_qops;
1082 	go->vidq.mem_ops = &vb2_vmalloc_memops;
1083 	go->vidq.drv_priv = go;
1084 	go->vidq.buf_struct_size = sizeof(struct go7007_buffer);
1085 	go->vidq.timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_MONOTONIC;
1086 	go->vidq.lock = &go->queue_lock;
1087 	rv = vb2_queue_init(&go->vidq);
1088 	if (rv)
1089 		return rv;
1090 	*vdev = go7007_template;
1091 	vdev->lock = &go->serialize_lock;
1092 	vdev->queue = &go->vidq;
1093 	vdev->device_caps = V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_READWRITE |
1094 			    V4L2_CAP_STREAMING;
1095 	if (go->board_info->num_aud_inputs)
1096 		vdev->device_caps |= V4L2_CAP_AUDIO;
1097 	if (go->board_info->flags & GO7007_BOARD_HAS_TUNER)
1098 		vdev->device_caps |= V4L2_CAP_TUNER;
1099 	video_set_drvdata(vdev, go);
1100 	vdev->v4l2_dev = &go->v4l2_dev;
1101 	if (!v4l2_device_has_op(&go->v4l2_dev, 0, video, querystd))
1102 		v4l2_disable_ioctl(vdev, VIDIOC_QUERYSTD);
1103 	if (!(go->board_info->flags & GO7007_BOARD_HAS_TUNER)) {
1104 		v4l2_disable_ioctl(vdev, VIDIOC_S_FREQUENCY);
1105 		v4l2_disable_ioctl(vdev, VIDIOC_G_FREQUENCY);
1106 		v4l2_disable_ioctl(vdev, VIDIOC_S_TUNER);
1107 		v4l2_disable_ioctl(vdev, VIDIOC_G_TUNER);
1108 	} else {
1109 		struct v4l2_frequency f = {
1110 			.type = V4L2_TUNER_ANALOG_TV,
1111 			.frequency = 980,
1112 		};
1113 
1114 		call_all(&go->v4l2_dev, tuner, s_frequency, &f);
1115 	}
1116 	if (!(go->board_info->sensor_flags & GO7007_SENSOR_TV)) {
1117 		v4l2_disable_ioctl(vdev, VIDIOC_G_STD);
1118 		v4l2_disable_ioctl(vdev, VIDIOC_S_STD);
1119 		vdev->tvnorms = 0;
1120 	}
1121 	if (go->board_info->sensor_flags & GO7007_SENSOR_SCALING)
1122 		v4l2_disable_ioctl(vdev, VIDIOC_ENUM_FRAMESIZES);
1123 	if (go->board_info->num_aud_inputs == 0) {
1124 		v4l2_disable_ioctl(vdev, VIDIOC_G_AUDIO);
1125 		v4l2_disable_ioctl(vdev, VIDIOC_S_AUDIO);
1126 		v4l2_disable_ioctl(vdev, VIDIOC_ENUMAUDIO);
1127 	}
1128 	/* Setup correct crystal frequency on this board */
1129 	if (go->board_info->sensor_flags & GO7007_SENSOR_SAA7115)
1130 		v4l2_subdev_call(go->sd_video, video, s_crystal_freq,
1131 				SAA7115_FREQ_24_576_MHZ,
1132 				SAA7115_FREQ_FL_APLL | SAA7115_FREQ_FL_UCGC |
1133 				SAA7115_FREQ_FL_DOUBLE_ASCLK);
1134 	go7007_s_input(go);
1135 	if (go->board_info->sensor_flags & GO7007_SENSOR_TV)
1136 		go7007_s_std(go);
1137 	rv = video_register_device(vdev, VFL_TYPE_VIDEO, -1);
1138 	if (rv < 0)
1139 		return rv;
1140 	dev_info(go->dev, "registered device %s [v4l2]\n",
1141 		 video_device_node_name(vdev));
1142 
1143 	return 0;
1144 }
1145 
1146 void go7007_v4l2_remove(struct go7007 *go)
1147 {
1148 	v4l2_ctrl_handler_free(&go->hdl);
1149 }
1150