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