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