1// SPDX-License-Identifier: GPL-2.0+
2/*
3 * Driver for Renesas R-Car VIN
4 *
5 * Copyright (C) 2016 Renesas Electronics Corp.
6 * Copyright (C) 2011-2013 Renesas Solutions Corp.
7 * Copyright (C) 2013 Cogent Embedded, Inc., <source@cogentembedded.com>
8 * Copyright (C) 2008 Magnus Damm
9 *
10 * Based on the soc-camera rcar_vin driver
11 */
12
13#include <linux/pm_runtime.h>
14
15#include <media/v4l2-event.h>
16#include <media/v4l2-ioctl.h>
17#include <media/v4l2-mc.h>
18#include <media/v4l2-rect.h>
19
20#include "rcar-vin.h"
21
22#define RVIN_DEFAULT_FORMAT	V4L2_PIX_FMT_YUYV
23#define RVIN_DEFAULT_WIDTH	800
24#define RVIN_DEFAULT_HEIGHT	600
25#define RVIN_DEFAULT_FIELD	V4L2_FIELD_NONE
26#define RVIN_DEFAULT_COLORSPACE	V4L2_COLORSPACE_SRGB
27
28/* -----------------------------------------------------------------------------
29 * Format Conversions
30 */
31
32static const struct rvin_video_format rvin_formats[] = {
33	{
34		.fourcc			= V4L2_PIX_FMT_NV12,
35		.bpp			= 1,
36	},
37	{
38		.fourcc			= V4L2_PIX_FMT_NV16,
39		.bpp			= 1,
40	},
41	{
42		.fourcc			= V4L2_PIX_FMT_YUYV,
43		.bpp			= 2,
44	},
45	{
46		.fourcc			= V4L2_PIX_FMT_UYVY,
47		.bpp			= 2,
48	},
49	{
50		.fourcc			= V4L2_PIX_FMT_RGB565,
51		.bpp			= 2,
52	},
53	{
54		.fourcc			= V4L2_PIX_FMT_XRGB555,
55		.bpp			= 2,
56	},
57	{
58		.fourcc			= V4L2_PIX_FMT_XBGR32,
59		.bpp			= 4,
60	},
61	{
62		.fourcc			= V4L2_PIX_FMT_ARGB555,
63		.bpp			= 2,
64	},
65	{
66		.fourcc			= V4L2_PIX_FMT_ABGR32,
67		.bpp			= 4,
68	},
69	{
70		.fourcc			= V4L2_PIX_FMT_SBGGR8,
71		.bpp			= 1,
72	},
73	{
74		.fourcc			= V4L2_PIX_FMT_SGBRG8,
75		.bpp			= 1,
76	},
77	{
78		.fourcc			= V4L2_PIX_FMT_SGRBG8,
79		.bpp			= 1,
80	},
81	{
82		.fourcc			= V4L2_PIX_FMT_SRGGB8,
83		.bpp			= 1,
84	},
85};
86
87const struct rvin_video_format *rvin_format_from_pixel(struct rvin_dev *vin,
88						       u32 pixelformat)
89{
90	int i;
91
92	switch (pixelformat) {
93	case V4L2_PIX_FMT_XBGR32:
94		if (vin->info->model == RCAR_M1)
95			return NULL;
96		break;
97	case V4L2_PIX_FMT_NV12:
98		/*
99		 * If NV12 is supported it's only supported on channels 0, 1, 4,
100		 * 5, 8, 9, 12 and 13.
101		 */
102		if (!vin->info->nv12 || !(BIT(vin->id) & 0x3333))
103			return NULL;
104		break;
105	default:
106		break;
107	}
108
109	for (i = 0; i < ARRAY_SIZE(rvin_formats); i++)
110		if (rvin_formats[i].fourcc == pixelformat)
111			return rvin_formats + i;
112
113	return NULL;
114}
115
116static u32 rvin_format_bytesperline(struct rvin_dev *vin,
117				    struct v4l2_pix_format *pix)
118{
119	const struct rvin_video_format *fmt;
120	u32 align;
121
122	fmt = rvin_format_from_pixel(vin, pix->pixelformat);
123
124	if (WARN_ON(!fmt))
125		return -EINVAL;
126
127	switch (pix->pixelformat) {
128	case V4L2_PIX_FMT_NV12:
129	case V4L2_PIX_FMT_NV16:
130		align = 0x20;
131		break;
132	default:
133		align = 0x10;
134		break;
135	}
136
137	if (V4L2_FIELD_IS_SEQUENTIAL(pix->field))
138		align = 0x80;
139
140	return ALIGN(pix->width, align) * fmt->bpp;
141}
142
143static u32 rvin_format_sizeimage(struct v4l2_pix_format *pix)
144{
145	switch (pix->pixelformat) {
146	case V4L2_PIX_FMT_NV12:
147		return pix->bytesperline * pix->height * 3 / 2;
148	case V4L2_PIX_FMT_NV16:
149		return pix->bytesperline * pix->height * 2;
150	default:
151		return pix->bytesperline * pix->height;
152	}
153}
154
155static void rvin_format_align(struct rvin_dev *vin, struct v4l2_pix_format *pix)
156{
157	u32 walign;
158
159	if (!rvin_format_from_pixel(vin, pix->pixelformat))
160		pix->pixelformat = RVIN_DEFAULT_FORMAT;
161
162	switch (pix->field) {
163	case V4L2_FIELD_TOP:
164	case V4L2_FIELD_BOTTOM:
165	case V4L2_FIELD_NONE:
166	case V4L2_FIELD_INTERLACED_TB:
167	case V4L2_FIELD_INTERLACED_BT:
168	case V4L2_FIELD_INTERLACED:
169	case V4L2_FIELD_ALTERNATE:
170	case V4L2_FIELD_SEQ_TB:
171	case V4L2_FIELD_SEQ_BT:
172		break;
173	default:
174		pix->field = RVIN_DEFAULT_FIELD;
175		break;
176	}
177
178	/* Hardware limits width alignment based on format. */
179	switch (pix->pixelformat) {
180	/* Multiple of 32 (2^5) for NV12/16. */
181	case V4L2_PIX_FMT_NV12:
182	case V4L2_PIX_FMT_NV16:
183		walign = 5;
184		break;
185	/* Multiple of 2 (2^1) for YUV. */
186	case V4L2_PIX_FMT_YUYV:
187	case V4L2_PIX_FMT_UYVY:
188		walign = 1;
189		break;
190	/* No multiple for RGB. */
191	default:
192		walign = 0;
193		break;
194	}
195
196	/* Limit to VIN capabilities */
197	v4l_bound_align_image(&pix->width, 5, vin->info->max_width, walign,
198			      &pix->height, 2, vin->info->max_height, 0, 0);
199
200	pix->bytesperline = rvin_format_bytesperline(vin, pix);
201	pix->sizeimage = rvin_format_sizeimage(pix);
202
203	vin_dbg(vin, "Format %ux%u bpl: %u size: %u\n",
204		pix->width, pix->height, pix->bytesperline, pix->sizeimage);
205}
206
207/* -----------------------------------------------------------------------------
208 * V4L2
209 */
210
211static int rvin_reset_format(struct rvin_dev *vin)
212{
213	struct v4l2_subdev_format fmt = {
214		.which = V4L2_SUBDEV_FORMAT_ACTIVE,
215		.pad = vin->parallel->source_pad,
216	};
217	int ret;
218
219	ret = v4l2_subdev_call(vin_to_source(vin), pad, get_fmt, NULL, &fmt);
220	if (ret)
221		return ret;
222
223	v4l2_fill_pix_format(&vin->format, &fmt.format);
224
225	vin->src_rect.top = 0;
226	vin->src_rect.left = 0;
227	vin->src_rect.width = vin->format.width;
228	vin->src_rect.height = vin->format.height;
229
230	/*  Make use of the hardware interlacer by default. */
231	if (vin->format.field == V4L2_FIELD_ALTERNATE) {
232		vin->format.field = V4L2_FIELD_INTERLACED;
233		vin->format.height *= 2;
234	}
235
236	rvin_format_align(vin, &vin->format);
237
238	vin->crop = vin->src_rect;
239
240	vin->compose.top = 0;
241	vin->compose.left = 0;
242	vin->compose.width = vin->format.width;
243	vin->compose.height = vin->format.height;
244
245	return 0;
246}
247
248static int rvin_try_format(struct rvin_dev *vin, u32 which,
249			   struct v4l2_pix_format *pix,
250			   struct v4l2_rect *src_rect)
251{
252	struct v4l2_subdev *sd = vin_to_source(vin);
253	struct v4l2_subdev_pad_config *pad_cfg;
254	struct v4l2_subdev_format format = {
255		.which = which,
256		.pad = vin->parallel->source_pad,
257	};
258	enum v4l2_field field;
259	u32 width, height;
260	int ret;
261
262	pad_cfg = v4l2_subdev_alloc_pad_config(sd);
263	if (pad_cfg == NULL)
264		return -ENOMEM;
265
266	if (!rvin_format_from_pixel(vin, pix->pixelformat))
267		pix->pixelformat = RVIN_DEFAULT_FORMAT;
268
269	v4l2_fill_mbus_format(&format.format, pix, vin->mbus_code);
270
271	/* Allow the video device to override field and to scale */
272	field = pix->field;
273	width = pix->width;
274	height = pix->height;
275
276	ret = v4l2_subdev_call(sd, pad, set_fmt, pad_cfg, &format);
277	if (ret < 0 && ret != -ENOIOCTLCMD)
278		goto done;
279	ret = 0;
280
281	v4l2_fill_pix_format(pix, &format.format);
282
283	if (src_rect) {
284		src_rect->top = 0;
285		src_rect->left = 0;
286		src_rect->width = pix->width;
287		src_rect->height = pix->height;
288	}
289
290	if (field != V4L2_FIELD_ANY)
291		pix->field = field;
292
293	pix->width = width;
294	pix->height = height;
295
296	rvin_format_align(vin, pix);
297done:
298	v4l2_subdev_free_pad_config(pad_cfg);
299
300	return ret;
301}
302
303static int rvin_querycap(struct file *file, void *priv,
304			 struct v4l2_capability *cap)
305{
306	struct rvin_dev *vin = video_drvdata(file);
307
308	strscpy(cap->driver, KBUILD_MODNAME, sizeof(cap->driver));
309	strscpy(cap->card, "R_Car_VIN", sizeof(cap->card));
310	snprintf(cap->bus_info, sizeof(cap->bus_info), "platform:%s",
311		 dev_name(vin->dev));
312	return 0;
313}
314
315static int rvin_try_fmt_vid_cap(struct file *file, void *priv,
316				struct v4l2_format *f)
317{
318	struct rvin_dev *vin = video_drvdata(file);
319
320	return rvin_try_format(vin, V4L2_SUBDEV_FORMAT_TRY, &f->fmt.pix, NULL);
321}
322
323static int rvin_s_fmt_vid_cap(struct file *file, void *priv,
324			      struct v4l2_format *f)
325{
326	struct rvin_dev *vin = video_drvdata(file);
327	struct v4l2_rect fmt_rect, src_rect;
328	int ret;
329
330	if (vb2_is_busy(&vin->queue))
331		return -EBUSY;
332
333	ret = rvin_try_format(vin, V4L2_SUBDEV_FORMAT_ACTIVE, &f->fmt.pix,
334			      &src_rect);
335	if (ret)
336		return ret;
337
338	vin->format = f->fmt.pix;
339
340	fmt_rect.top = 0;
341	fmt_rect.left = 0;
342	fmt_rect.width = vin->format.width;
343	fmt_rect.height = vin->format.height;
344
345	v4l2_rect_map_inside(&vin->crop, &src_rect);
346	v4l2_rect_map_inside(&vin->compose, &fmt_rect);
347	vin->src_rect = src_rect;
348
349	return 0;
350}
351
352static int rvin_g_fmt_vid_cap(struct file *file, void *priv,
353			      struct v4l2_format *f)
354{
355	struct rvin_dev *vin = video_drvdata(file);
356
357	f->fmt.pix = vin->format;
358
359	return 0;
360}
361
362static int rvin_enum_fmt_vid_cap(struct file *file, void *priv,
363				 struct v4l2_fmtdesc *f)
364{
365	struct rvin_dev *vin = video_drvdata(file);
366	unsigned int i;
367	int matched;
368
369	/*
370	 * If mbus_code is set only enumerate supported pixel formats for that
371	 * bus code. Converting from YCbCr to RGB and RGB to YCbCr is possible
372	 * with VIN, so all supported YCbCr and RGB media bus codes can produce
373	 * all of the related pixel formats. If mbus_code is not set enumerate
374	 * all possible pixelformats.
375	 *
376	 * TODO: Once raw MEDIA_BUS_FMT_SRGGB12_1X12 format is added to the
377	 * driver this needs to be extended so raw media bus code only result in
378	 * raw pixel format.
379	 */
380	switch (f->mbus_code) {
381	case 0:
382	case MEDIA_BUS_FMT_YUYV8_1X16:
383	case MEDIA_BUS_FMT_UYVY8_1X16:
384	case MEDIA_BUS_FMT_UYVY8_2X8:
385	case MEDIA_BUS_FMT_UYVY10_2X10:
386	case MEDIA_BUS_FMT_RGB888_1X24:
387		break;
388	case MEDIA_BUS_FMT_SBGGR8_1X8:
389		if (f->index)
390			return -EINVAL;
391		f->pixelformat = V4L2_PIX_FMT_SBGGR8;
392		return 0;
393	case MEDIA_BUS_FMT_SGBRG8_1X8:
394		if (f->index)
395			return -EINVAL;
396		f->pixelformat = V4L2_PIX_FMT_SGBRG8;
397		return 0;
398	case MEDIA_BUS_FMT_SGRBG8_1X8:
399		if (f->index)
400			return -EINVAL;
401		f->pixelformat = V4L2_PIX_FMT_SGRBG8;
402		return 0;
403	case MEDIA_BUS_FMT_SRGGB8_1X8:
404		if (f->index)
405			return -EINVAL;
406		f->pixelformat = V4L2_PIX_FMT_SRGGB8;
407		return 0;
408	default:
409		return -EINVAL;
410	}
411
412	matched = -1;
413	for (i = 0; i < ARRAY_SIZE(rvin_formats); i++) {
414		if (rvin_format_from_pixel(vin, rvin_formats[i].fourcc))
415			matched++;
416
417		if (matched == f->index) {
418			f->pixelformat = rvin_formats[i].fourcc;
419			return 0;
420		}
421	}
422
423	return -EINVAL;
424}
425
426static int rvin_g_selection(struct file *file, void *fh,
427			    struct v4l2_selection *s)
428{
429	struct rvin_dev *vin = video_drvdata(file);
430
431	if (s->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
432		return -EINVAL;
433
434	switch (s->target) {
435	case V4L2_SEL_TGT_CROP_BOUNDS:
436	case V4L2_SEL_TGT_CROP_DEFAULT:
437		s->r.left = s->r.top = 0;
438		s->r.width = vin->src_rect.width;
439		s->r.height = vin->src_rect.height;
440		break;
441	case V4L2_SEL_TGT_CROP:
442		s->r = vin->crop;
443		break;
444	case V4L2_SEL_TGT_COMPOSE_BOUNDS:
445	case V4L2_SEL_TGT_COMPOSE_DEFAULT:
446		s->r.left = s->r.top = 0;
447		s->r.width = vin->format.width;
448		s->r.height = vin->format.height;
449		break;
450	case V4L2_SEL_TGT_COMPOSE:
451		s->r = vin->compose;
452		break;
453	default:
454		return -EINVAL;
455	}
456
457	return 0;
458}
459
460static int rvin_s_selection(struct file *file, void *fh,
461			    struct v4l2_selection *s)
462{
463	struct rvin_dev *vin = video_drvdata(file);
464	const struct rvin_video_format *fmt;
465	struct v4l2_rect r = s->r;
466	struct v4l2_rect max_rect;
467	struct v4l2_rect min_rect = {
468		.width = 6,
469		.height = 2,
470	};
471
472	if (s->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
473		return -EINVAL;
474
475	v4l2_rect_set_min_size(&r, &min_rect);
476
477	switch (s->target) {
478	case V4L2_SEL_TGT_CROP:
479		/* Can't crop outside of source input */
480		max_rect.top = max_rect.left = 0;
481		max_rect.width = vin->src_rect.width;
482		max_rect.height = vin->src_rect.height;
483		v4l2_rect_map_inside(&r, &max_rect);
484
485		v4l_bound_align_image(&r.width, 6, vin->src_rect.width, 0,
486				      &r.height, 2, vin->src_rect.height, 0, 0);
487
488		r.top  = clamp_t(s32, r.top, 0,
489				 vin->src_rect.height - r.height);
490		r.left = clamp_t(s32, r.left, 0, vin->src_rect.width - r.width);
491
492		vin->crop = s->r = r;
493
494		vin_dbg(vin, "Cropped %dx%d@%d:%d of %dx%d\n",
495			r.width, r.height, r.left, r.top,
496			vin->src_rect.width, vin->src_rect.height);
497		break;
498	case V4L2_SEL_TGT_COMPOSE:
499		/* Make sure compose rect fits inside output format */
500		max_rect.top = max_rect.left = 0;
501		max_rect.width = vin->format.width;
502		max_rect.height = vin->format.height;
503		v4l2_rect_map_inside(&r, &max_rect);
504
505		/*
506		 * Composing is done by adding a offset to the buffer address,
507		 * the HW wants this address to be aligned to HW_BUFFER_MASK.
508		 * Make sure the top and left values meets this requirement.
509		 */
510		while ((r.top * vin->format.bytesperline) & HW_BUFFER_MASK)
511			r.top--;
512
513		fmt = rvin_format_from_pixel(vin, vin->format.pixelformat);
514		while ((r.left * fmt->bpp) & HW_BUFFER_MASK)
515			r.left--;
516
517		vin->compose = s->r = r;
518
519		vin_dbg(vin, "Compose %dx%d@%d:%d in %dx%d\n",
520			r.width, r.height, r.left, r.top,
521			vin->format.width, vin->format.height);
522		break;
523	default:
524		return -EINVAL;
525	}
526
527	/* HW supports modifying configuration while running */
528	rvin_crop_scale_comp(vin);
529
530	return 0;
531}
532
533static int rvin_g_pixelaspect(struct file *file, void *priv,
534			      int type, struct v4l2_fract *f)
535{
536	struct rvin_dev *vin = video_drvdata(file);
537	struct v4l2_subdev *sd = vin_to_source(vin);
538
539	if (type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
540		return -EINVAL;
541
542	return v4l2_subdev_call(sd, video, g_pixelaspect, f);
543}
544
545static int rvin_enum_input(struct file *file, void *priv,
546			   struct v4l2_input *i)
547{
548	struct rvin_dev *vin = video_drvdata(file);
549	struct v4l2_subdev *sd = vin_to_source(vin);
550	int ret;
551
552	if (i->index != 0)
553		return -EINVAL;
554
555	ret = v4l2_subdev_call(sd, video, g_input_status, &i->status);
556	if (ret < 0 && ret != -ENOIOCTLCMD && ret != -ENODEV)
557		return ret;
558
559	i->type = V4L2_INPUT_TYPE_CAMERA;
560
561	if (v4l2_subdev_has_op(sd, pad, dv_timings_cap)) {
562		i->capabilities = V4L2_IN_CAP_DV_TIMINGS;
563		i->std = 0;
564	} else {
565		i->capabilities = V4L2_IN_CAP_STD;
566		i->std = vin->vdev.tvnorms;
567	}
568
569	strscpy(i->name, "Camera", sizeof(i->name));
570
571	return 0;
572}
573
574static int rvin_g_input(struct file *file, void *priv, unsigned int *i)
575{
576	*i = 0;
577	return 0;
578}
579
580static int rvin_s_input(struct file *file, void *priv, unsigned int i)
581{
582	if (i > 0)
583		return -EINVAL;
584	return 0;
585}
586
587static int rvin_querystd(struct file *file, void *priv, v4l2_std_id *a)
588{
589	struct rvin_dev *vin = video_drvdata(file);
590	struct v4l2_subdev *sd = vin_to_source(vin);
591
592	return v4l2_subdev_call(sd, video, querystd, a);
593}
594
595static int rvin_s_std(struct file *file, void *priv, v4l2_std_id a)
596{
597	struct rvin_dev *vin = video_drvdata(file);
598	int ret;
599
600	ret = v4l2_subdev_call(vin_to_source(vin), video, s_std, a);
601	if (ret < 0)
602		return ret;
603
604	vin->std = a;
605
606	/* Changing the standard will change the width/height */
607	return rvin_reset_format(vin);
608}
609
610static int rvin_g_std(struct file *file, void *priv, v4l2_std_id *a)
611{
612	struct rvin_dev *vin = video_drvdata(file);
613
614	if (v4l2_subdev_has_op(vin_to_source(vin), pad, dv_timings_cap))
615		return -ENOIOCTLCMD;
616
617	*a = vin->std;
618
619	return 0;
620}
621
622static int rvin_subscribe_event(struct v4l2_fh *fh,
623				const struct v4l2_event_subscription *sub)
624{
625	switch (sub->type) {
626	case V4L2_EVENT_SOURCE_CHANGE:
627		return v4l2_event_subscribe(fh, sub, 4, NULL);
628	}
629	return v4l2_ctrl_subscribe_event(fh, sub);
630}
631
632static int rvin_enum_dv_timings(struct file *file, void *priv_fh,
633				struct v4l2_enum_dv_timings *timings)
634{
635	struct rvin_dev *vin = video_drvdata(file);
636	struct v4l2_subdev *sd = vin_to_source(vin);
637	int ret;
638
639	if (timings->pad)
640		return -EINVAL;
641
642	timings->pad = vin->parallel->sink_pad;
643
644	ret = v4l2_subdev_call(sd, pad, enum_dv_timings, timings);
645
646	timings->pad = 0;
647
648	return ret;
649}
650
651static int rvin_s_dv_timings(struct file *file, void *priv_fh,
652			     struct v4l2_dv_timings *timings)
653{
654	struct rvin_dev *vin = video_drvdata(file);
655	struct v4l2_subdev *sd = vin_to_source(vin);
656	int ret;
657
658	ret = v4l2_subdev_call(sd, video, s_dv_timings, timings);
659	if (ret)
660		return ret;
661
662	/* Changing the timings will change the width/height */
663	return rvin_reset_format(vin);
664}
665
666static int rvin_g_dv_timings(struct file *file, void *priv_fh,
667			     struct v4l2_dv_timings *timings)
668{
669	struct rvin_dev *vin = video_drvdata(file);
670	struct v4l2_subdev *sd = vin_to_source(vin);
671
672	return v4l2_subdev_call(sd, video, g_dv_timings, timings);
673}
674
675static int rvin_query_dv_timings(struct file *file, void *priv_fh,
676				 struct v4l2_dv_timings *timings)
677{
678	struct rvin_dev *vin = video_drvdata(file);
679	struct v4l2_subdev *sd = vin_to_source(vin);
680
681	return v4l2_subdev_call(sd, video, query_dv_timings, timings);
682}
683
684static int rvin_dv_timings_cap(struct file *file, void *priv_fh,
685			       struct v4l2_dv_timings_cap *cap)
686{
687	struct rvin_dev *vin = video_drvdata(file);
688	struct v4l2_subdev *sd = vin_to_source(vin);
689	int ret;
690
691	if (cap->pad)
692		return -EINVAL;
693
694	cap->pad = vin->parallel->sink_pad;
695
696	ret = v4l2_subdev_call(sd, pad, dv_timings_cap, cap);
697
698	cap->pad = 0;
699
700	return ret;
701}
702
703static int rvin_g_edid(struct file *file, void *fh, struct v4l2_edid *edid)
704{
705	struct rvin_dev *vin = video_drvdata(file);
706	struct v4l2_subdev *sd = vin_to_source(vin);
707	int ret;
708
709	if (edid->pad)
710		return -EINVAL;
711
712	edid->pad = vin->parallel->sink_pad;
713
714	ret = v4l2_subdev_call(sd, pad, get_edid, edid);
715
716	edid->pad = 0;
717
718	return ret;
719}
720
721static int rvin_s_edid(struct file *file, void *fh, struct v4l2_edid *edid)
722{
723	struct rvin_dev *vin = video_drvdata(file);
724	struct v4l2_subdev *sd = vin_to_source(vin);
725	int ret;
726
727	if (edid->pad)
728		return -EINVAL;
729
730	edid->pad = vin->parallel->sink_pad;
731
732	ret = v4l2_subdev_call(sd, pad, set_edid, edid);
733
734	edid->pad = 0;
735
736	return ret;
737}
738
739static const struct v4l2_ioctl_ops rvin_ioctl_ops = {
740	.vidioc_querycap		= rvin_querycap,
741	.vidioc_try_fmt_vid_cap		= rvin_try_fmt_vid_cap,
742	.vidioc_g_fmt_vid_cap		= rvin_g_fmt_vid_cap,
743	.vidioc_s_fmt_vid_cap		= rvin_s_fmt_vid_cap,
744	.vidioc_enum_fmt_vid_cap	= rvin_enum_fmt_vid_cap,
745
746	.vidioc_g_selection		= rvin_g_selection,
747	.vidioc_s_selection		= rvin_s_selection,
748
749	.vidioc_g_pixelaspect		= rvin_g_pixelaspect,
750
751	.vidioc_enum_input		= rvin_enum_input,
752	.vidioc_g_input			= rvin_g_input,
753	.vidioc_s_input			= rvin_s_input,
754
755	.vidioc_dv_timings_cap		= rvin_dv_timings_cap,
756	.vidioc_enum_dv_timings		= rvin_enum_dv_timings,
757	.vidioc_g_dv_timings		= rvin_g_dv_timings,
758	.vidioc_s_dv_timings		= rvin_s_dv_timings,
759	.vidioc_query_dv_timings	= rvin_query_dv_timings,
760
761	.vidioc_g_edid			= rvin_g_edid,
762	.vidioc_s_edid			= rvin_s_edid,
763
764	.vidioc_querystd		= rvin_querystd,
765	.vidioc_g_std			= rvin_g_std,
766	.vidioc_s_std			= rvin_s_std,
767
768	.vidioc_reqbufs			= vb2_ioctl_reqbufs,
769	.vidioc_create_bufs		= vb2_ioctl_create_bufs,
770	.vidioc_querybuf		= vb2_ioctl_querybuf,
771	.vidioc_qbuf			= vb2_ioctl_qbuf,
772	.vidioc_dqbuf			= vb2_ioctl_dqbuf,
773	.vidioc_expbuf			= vb2_ioctl_expbuf,
774	.vidioc_prepare_buf		= vb2_ioctl_prepare_buf,
775	.vidioc_streamon		= vb2_ioctl_streamon,
776	.vidioc_streamoff		= vb2_ioctl_streamoff,
777
778	.vidioc_log_status		= v4l2_ctrl_log_status,
779	.vidioc_subscribe_event		= rvin_subscribe_event,
780	.vidioc_unsubscribe_event	= v4l2_event_unsubscribe,
781};
782
783/* -----------------------------------------------------------------------------
784 * V4L2 Media Controller
785 */
786
787static void rvin_mc_try_format(struct rvin_dev *vin,
788			       struct v4l2_pix_format *pix)
789{
790	/*
791	 * The V4L2 specification clearly documents the colorspace fields
792	 * as being set by drivers for capture devices. Using the values
793	 * supplied by userspace thus wouldn't comply with the API. Until
794	 * the API is updated force fixed values.
795	 */
796	pix->colorspace = RVIN_DEFAULT_COLORSPACE;
797	pix->xfer_func = V4L2_MAP_XFER_FUNC_DEFAULT(pix->colorspace);
798	pix->ycbcr_enc = V4L2_MAP_YCBCR_ENC_DEFAULT(pix->colorspace);
799	pix->quantization = V4L2_MAP_QUANTIZATION_DEFAULT(true, pix->colorspace,
800							  pix->ycbcr_enc);
801
802	rvin_format_align(vin, pix);
803}
804
805static int rvin_mc_try_fmt_vid_cap(struct file *file, void *priv,
806				   struct v4l2_format *f)
807{
808	struct rvin_dev *vin = video_drvdata(file);
809
810	rvin_mc_try_format(vin, &f->fmt.pix);
811
812	return 0;
813}
814
815static int rvin_mc_s_fmt_vid_cap(struct file *file, void *priv,
816				 struct v4l2_format *f)
817{
818	struct rvin_dev *vin = video_drvdata(file);
819
820	if (vb2_is_busy(&vin->queue))
821		return -EBUSY;
822
823	rvin_mc_try_format(vin, &f->fmt.pix);
824
825	vin->format = f->fmt.pix;
826
827	vin->crop.top = 0;
828	vin->crop.left = 0;
829	vin->crop.width = vin->format.width;
830	vin->crop.height = vin->format.height;
831	vin->compose = vin->crop;
832
833	return 0;
834}
835
836static const struct v4l2_ioctl_ops rvin_mc_ioctl_ops = {
837	.vidioc_querycap		= rvin_querycap,
838	.vidioc_try_fmt_vid_cap		= rvin_mc_try_fmt_vid_cap,
839	.vidioc_g_fmt_vid_cap		= rvin_g_fmt_vid_cap,
840	.vidioc_s_fmt_vid_cap		= rvin_mc_s_fmt_vid_cap,
841	.vidioc_enum_fmt_vid_cap	= rvin_enum_fmt_vid_cap,
842
843	.vidioc_reqbufs			= vb2_ioctl_reqbufs,
844	.vidioc_create_bufs		= vb2_ioctl_create_bufs,
845	.vidioc_querybuf		= vb2_ioctl_querybuf,
846	.vidioc_qbuf			= vb2_ioctl_qbuf,
847	.vidioc_dqbuf			= vb2_ioctl_dqbuf,
848	.vidioc_expbuf			= vb2_ioctl_expbuf,
849	.vidioc_prepare_buf		= vb2_ioctl_prepare_buf,
850	.vidioc_streamon		= vb2_ioctl_streamon,
851	.vidioc_streamoff		= vb2_ioctl_streamoff,
852
853	.vidioc_log_status		= v4l2_ctrl_log_status,
854	.vidioc_subscribe_event		= rvin_subscribe_event,
855	.vidioc_unsubscribe_event	= v4l2_event_unsubscribe,
856};
857
858/* -----------------------------------------------------------------------------
859 * File Operations
860 */
861
862static int rvin_power_parallel(struct rvin_dev *vin, bool on)
863{
864	struct v4l2_subdev *sd = vin_to_source(vin);
865	int power = on ? 1 : 0;
866	int ret;
867
868	ret = v4l2_subdev_call(sd, core, s_power, power);
869	if (ret < 0 && ret != -ENOIOCTLCMD && ret != -ENODEV)
870		return ret;
871
872	return 0;
873}
874
875static int rvin_open(struct file *file)
876{
877	struct rvin_dev *vin = video_drvdata(file);
878	int ret;
879
880	ret = pm_runtime_get_sync(vin->dev);
881	if (ret < 0) {
882		pm_runtime_put_noidle(vin->dev);
883		return ret;
884	}
885
886	ret = mutex_lock_interruptible(&vin->lock);
887	if (ret)
888		goto err_pm;
889
890	file->private_data = vin;
891
892	ret = v4l2_fh_open(file);
893	if (ret)
894		goto err_unlock;
895
896	if (vin->info->use_mc)
897		ret = v4l2_pipeline_pm_get(&vin->vdev.entity);
898	else if (v4l2_fh_is_singular_file(file))
899		ret = rvin_power_parallel(vin, true);
900
901	if (ret < 0)
902		goto err_open;
903
904	ret = v4l2_ctrl_handler_setup(&vin->ctrl_handler);
905	if (ret)
906		goto err_power;
907
908	mutex_unlock(&vin->lock);
909
910	return 0;
911err_power:
912	if (vin->info->use_mc)
913		v4l2_pipeline_pm_put(&vin->vdev.entity);
914	else if (v4l2_fh_is_singular_file(file))
915		rvin_power_parallel(vin, false);
916err_open:
917	v4l2_fh_release(file);
918err_unlock:
919	mutex_unlock(&vin->lock);
920err_pm:
921	pm_runtime_put(vin->dev);
922
923	return ret;
924}
925
926static int rvin_release(struct file *file)
927{
928	struct rvin_dev *vin = video_drvdata(file);
929	bool fh_singular;
930	int ret;
931
932	mutex_lock(&vin->lock);
933
934	/* Save the singular status before we call the clean-up helper */
935	fh_singular = v4l2_fh_is_singular_file(file);
936
937	/* the release helper will cleanup any on-going streaming */
938	ret = _vb2_fop_release(file, NULL);
939
940	if (vin->info->use_mc) {
941		v4l2_pipeline_pm_put(&vin->vdev.entity);
942	} else {
943		if (fh_singular)
944			rvin_power_parallel(vin, false);
945	}
946
947	mutex_unlock(&vin->lock);
948
949	pm_runtime_put(vin->dev);
950
951	return ret;
952}
953
954static const struct v4l2_file_operations rvin_fops = {
955	.owner		= THIS_MODULE,
956	.unlocked_ioctl	= video_ioctl2,
957	.open		= rvin_open,
958	.release	= rvin_release,
959	.poll		= vb2_fop_poll,
960	.mmap		= vb2_fop_mmap,
961	.read		= vb2_fop_read,
962};
963
964void rvin_v4l2_unregister(struct rvin_dev *vin)
965{
966	if (!video_is_registered(&vin->vdev))
967		return;
968
969	v4l2_info(&vin->v4l2_dev, "Removing %s\n",
970		  video_device_node_name(&vin->vdev));
971
972	/* Checks internally if vdev have been init or not */
973	video_unregister_device(&vin->vdev);
974}
975
976static void rvin_notify(struct v4l2_subdev *sd,
977			unsigned int notification, void *arg)
978{
979	struct rvin_dev *vin =
980		container_of(sd->v4l2_dev, struct rvin_dev, v4l2_dev);
981
982	switch (notification) {
983	case V4L2_DEVICE_NOTIFY_EVENT:
984		v4l2_event_queue(&vin->vdev, arg);
985		break;
986	default:
987		break;
988	}
989}
990
991int rvin_v4l2_register(struct rvin_dev *vin)
992{
993	struct video_device *vdev = &vin->vdev;
994	int ret;
995
996	vin->v4l2_dev.notify = rvin_notify;
997
998	/* video node */
999	vdev->v4l2_dev = &vin->v4l2_dev;
1000	vdev->queue = &vin->queue;
1001	snprintf(vdev->name, sizeof(vdev->name), "VIN%u output", vin->id);
1002	vdev->release = video_device_release_empty;
1003	vdev->lock = &vin->lock;
1004	vdev->fops = &rvin_fops;
1005	vdev->device_caps = V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_STREAMING |
1006		V4L2_CAP_READWRITE;
1007
1008	/* Set a default format */
1009	vin->format.pixelformat	= RVIN_DEFAULT_FORMAT;
1010	vin->format.width = RVIN_DEFAULT_WIDTH;
1011	vin->format.height = RVIN_DEFAULT_HEIGHT;
1012	vin->format.field = RVIN_DEFAULT_FIELD;
1013	vin->format.colorspace = RVIN_DEFAULT_COLORSPACE;
1014
1015	if (vin->info->use_mc) {
1016		vdev->device_caps |= V4L2_CAP_IO_MC;
1017		vdev->ioctl_ops = &rvin_mc_ioctl_ops;
1018	} else {
1019		vdev->ioctl_ops = &rvin_ioctl_ops;
1020		rvin_reset_format(vin);
1021	}
1022
1023	rvin_format_align(vin, &vin->format);
1024
1025	ret = video_register_device(&vin->vdev, VFL_TYPE_VIDEO, -1);
1026	if (ret) {
1027		vin_err(vin, "Failed to register video device\n");
1028		return ret;
1029	}
1030
1031	video_set_drvdata(&vin->vdev, vin);
1032
1033	v4l2_info(&vin->v4l2_dev, "Device registered as %s\n",
1034		  video_device_node_name(&vin->vdev));
1035
1036	return ret;
1037}
1038