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