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