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