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